[#932] adm: Refactor command morph

Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
This commit is contained in:
Anton Nikiforov 2024-01-31 17:26:26 +03:00
parent 0bd030507e
commit cda3a3d834
26 changed files with 324 additions and 290 deletions

View file

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
parseutil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util" parseutil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
@ -41,7 +42,7 @@ var (
Use: "add-rule-chain", Use: "add-rule-chain",
Short: "Add rule chain", Short: "Add rule chain",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
}, },
Run: addRuleChain, Run: addRuleChain,
@ -51,7 +52,7 @@ var (
Use: "rm-rule-chain", Use: "rm-rule-chain",
Short: "Remove rule chain", Short: "Remove rule chain",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
}, },
Run: removeRuleChain, Run: removeRuleChain,
@ -61,7 +62,7 @@ var (
Use: "list-rule-chains", Use: "list-rule-chains",
Short: "List rule chains", Short: "List rule chains",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
}, },
Run: listRuleChains, Run: listRuleChains,
@ -71,7 +72,7 @@ var (
Use: "set-admin", Use: "set-admin",
Short: "Set admin", Short: "Set admin",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
}, },
Run: setAdmin, Run: setAdmin,
@ -81,7 +82,7 @@ var (
Use: "get-admin", Use: "get-admin",
Short: "Get admin", Short: "Get admin",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
}, },
Run: getAdmin, Run: getAdmin,
@ -91,7 +92,7 @@ var (
func initAddRuleChainCmd() { func initAddRuleChainCmd() {
apeCmd.AddCommand(addRuleChainCmd) apeCmd.AddCommand(addRuleChainCmd)
addRuleChainCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) addRuleChainCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
addRuleChainCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) addRuleChainCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
addRuleChainCmd.Flags().String(targetTypeFlag, "", targetTypeDesc) addRuleChainCmd.Flags().String(targetTypeFlag, "", targetTypeDesc)
@ -110,7 +111,7 @@ func initAddRuleChainCmd() {
func initRemoveRuleChainCmd() { func initRemoveRuleChainCmd() {
apeCmd.AddCommand(removeRuleChainCmd) apeCmd.AddCommand(removeRuleChainCmd)
removeRuleChainCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) removeRuleChainCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
removeRuleChainCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) removeRuleChainCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
removeRuleChainCmd.Flags().String(targetTypeFlag, "", targetTypeDesc) removeRuleChainCmd.Flags().String(targetTypeFlag, "", targetTypeDesc)
@ -124,7 +125,7 @@ func initRemoveRuleChainCmd() {
func initListRuleChainsCmd() { func initListRuleChainsCmd() {
apeCmd.AddCommand(listRuleChainsCmd) apeCmd.AddCommand(listRuleChainsCmd)
listRuleChainsCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) listRuleChainsCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
listRuleChainsCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) listRuleChainsCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
listRuleChainsCmd.Flags().StringP(targetTypeFlag, "t", "", targetTypeDesc) listRuleChainsCmd.Flags().StringP(targetTypeFlag, "t", "", targetTypeDesc)
_ = listRuleChainsCmd.MarkFlagRequired(targetTypeFlag) _ = listRuleChainsCmd.MarkFlagRequired(targetTypeFlag)
@ -136,7 +137,7 @@ func initListRuleChainsCmd() {
func initSetAdminCmd() { func initSetAdminCmd() {
apeCmd.AddCommand(setAdminCmd) apeCmd.AddCommand(setAdminCmd)
setAdminCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) setAdminCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
setAdminCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) setAdminCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
setAdminCmd.Flags().String(addrAdminFlag, "", addrAdminDesc) setAdminCmd.Flags().String(addrAdminFlag, "", addrAdminDesc)
_ = setAdminCmd.MarkFlagRequired(addrAdminFlag) _ = setAdminCmd.MarkFlagRequired(addrAdminFlag)
@ -145,7 +146,7 @@ func initSetAdminCmd() {
func initGetAdminCmd() { func initGetAdminCmd() {
apeCmd.AddCommand(getAdminCmd) apeCmd.AddCommand(getAdminCmd)
getAdminCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) getAdminCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
getAdminCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) getAdminCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
} }

View file

@ -6,6 +6,7 @@ import (
"os" "os"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
parseutil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util" parseutil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
@ -77,17 +78,17 @@ func parseChain(cmd *cobra.Command) *apechain.Chain {
func newPolicyContractInterface(cmd *cobra.Command) (*morph.ContractStorage, *actor.Actor) { func newPolicyContractInterface(cmd *cobra.Command) (*morph.ContractStorage, *actor.Actor) {
v := viper.GetViper() v := viper.GetViper()
c, err := getN3Client(v) c, err := morphUtil.GetN3Client(v)
commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err) commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err)
walletDir := config.ResolveHomePath(viper.GetString(alphabetWalletsFlag)) walletDir := config.ResolveHomePath(viper.GetString(alphabetWalletsFlag))
wallets, err := getAlphabetWallets(v, walletDir) wallets, err := morphUtil.GetAlphabetWallets(v, walletDir)
commonCmd.ExitOnErr(cmd, "unable to get alphabet wallets: %w", err) commonCmd.ExitOnErr(cmd, "unable to get alphabet wallets: %w", err)
committeeAcc, err := getWalletAccount(wallets[0], committeeAccountName) committeeAcc, err := morphUtil.GetWalletAccount(wallets[0], committeeAccountName)
commonCmd.ExitOnErr(cmd, "can't find committee account: %w", err) commonCmd.ExitOnErr(cmd, "can't find committee account: %w", err)
ac, err := newActor(c, committeeAcc) ac, err := morphUtil.NewActor(c, committeeAcc)
commonCmd.ExitOnErr(cmd, "can't create actor: %w", err) commonCmd.ExitOnErr(cmd, "can't create actor: %w", err)
inv := &ac.Invoker inv := &ac.Invoker

View file

@ -7,6 +7,7 @@ import (
"math/big" "math/big"
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns" "git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles" "github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
@ -49,7 +50,7 @@ func dumpBalances(cmd *cobra.Command, _ []string) error {
nmHash util.Uint160 nmHash util.Uint160
) )
c, err := getN3Client(viper.GetViper()) c, err := morphUtil.GetN3Client(viper.GetViper())
if err != nil { if err != nil {
return err return err
} }
@ -150,7 +151,7 @@ func printProxyContractBalance(cmd *cobra.Command, inv *invoker.Invoker, nnsHash
return nil return nil
} }
func printAlphabetContractBalances(cmd *cobra.Command, c Client, inv *invoker.Invoker, count int, nnsHash util.Uint160) error { func printAlphabetContractBalances(cmd *cobra.Command, c morphUtil.Client, inv *invoker.Invoker, count int, nnsHash util.Uint160) error {
alphaList := make([]accBalancePair, count) alphaList := make([]accBalancePair, count)
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
@ -184,7 +185,7 @@ func printAlphabetContractBalances(cmd *cobra.Command, c Client, inv *invoker.In
return nil return nil
} }
func fetchIRNodes(c Client, desigHash util.Uint160) ([]accBalancePair, error) { func fetchIRNodes(c morphUtil.Client, desigHash util.Uint160) ([]accBalancePair, error) {
inv := invoker.New(c, nil) inv := invoker.New(c, nil)
height, err := c.GetBlockCount() height, err := c.GetBlockCount()
@ -192,7 +193,7 @@ func fetchIRNodes(c Client, desigHash util.Uint160) ([]accBalancePair, error) {
return nil, fmt.Errorf("can't get block height: %w", err) return nil, fmt.Errorf("can't get block height: %w", err)
} }
arr, err := getDesignatedByRole(inv, desigHash, noderoles.NeoFSAlphabet, height) arr, err := morphUtil.GetDesignatedByRole(inv, desigHash, noderoles.NeoFSAlphabet, height)
if err != nil { if err != nil {
return nil, errors.New("can't fetch list of IR nodes from the netmap contract") return nil, errors.New("can't fetch list of IR nodes from the netmap contract")
} }

View file

@ -10,6 +10,7 @@ import (
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker" "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
@ -24,7 +25,7 @@ import (
const forceConfigSet = "force" const forceConfigSet = "force"
func dumpNetworkConfig(cmd *cobra.Command, _ []string) error { func dumpNetworkConfig(cmd *cobra.Command, _ []string) error {
c, err := getN3Client(viper.GetViper()) c, err := util.GetN3Client(viper.GetViper())
if err != nil { if err != nil {
return fmt.Errorf("can't create N3 client: %w", err) return fmt.Errorf("can't create N3 client: %w", err)
} }

View file

@ -7,6 +7,7 @@ import (
"os" "os"
"sort" "sort"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
@ -73,7 +74,7 @@ func dumpContainers(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("invalid filename: %w", err) return fmt.Errorf("invalid filename: %w", err)
} }
c, err := getN3Client(viper.GetViper()) c, err := morphUtil.GetN3Client(viper.GetViper())
if err != nil { if err != nil {
return fmt.Errorf("can't create N3 client: %w", err) return fmt.Errorf("can't create N3 client: %w", err)
} }
@ -163,7 +164,7 @@ func dumpSingleContainer(bw *io.BufBinWriter, ch util.Uint160, inv *invoker.Invo
} }
func listContainers(cmd *cobra.Command, _ []string) error { func listContainers(cmd *cobra.Command, _ []string) error {
c, err := getN3Client(viper.GetViper()) c, err := morphUtil.GetN3Client(viper.GetViper())
if err != nil { if err != nil {
return fmt.Errorf("can't create N3 client: %w", err) return fmt.Errorf("can't create N3 client: %w", err)
} }

View file

@ -7,6 +7,7 @@ import (
"strings" "strings"
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns" "git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
"github.com/nspcc-dev/neo-go/cli/cmdargs" "github.com/nspcc-dev/neo-go/cli/cmdargs"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
@ -38,7 +39,7 @@ Contract's manifest file name must be 'config.json'.
NNS name is taken by stripping '_contract.nef' from the NEF file (similar to frostfs contracts).`, NNS name is taken by stripping '_contract.nef' from the NEF file (similar to frostfs contracts).`,
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: deployContractCmd, RunE: deployContractCmd,
} }
@ -49,7 +50,7 @@ func init() {
ff.String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) ff.String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
_ = deployCmd.MarkFlagFilename(alphabetWalletsFlag) _ = deployCmd.MarkFlagFilename(alphabetWalletsFlag)
ff.StringP(endpointFlag, "r", "", endpointFlagDesc) ff.StringP(util.EndpointFlag, "r", "", util.EndpointFlagDesc)
ff.String(contractPathFlag, "", "Path to the contract directory") ff.String(contractPathFlag, "", "Path to the contract directory")
_ = deployCmd.MarkFlagFilename(contractPathFlag) _ = deployCmd.MarkFlagFilename(contractPathFlag)

View file

@ -8,6 +8,7 @@ import (
"text/tabwriter" "text/tabwriter"
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns" "git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client" morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker" "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
@ -33,7 +34,7 @@ type contractDumpInfo struct {
} }
func dumpContractHashes(cmd *cobra.Command, _ []string) error { func dumpContractHashes(cmd *cobra.Command, _ []string) error {
c, err := getN3Client(viper.GetViper()) c, err := morphUtil.GetN3Client(viper.GetViper())
if err != nil { if err != nil {
return fmt.Errorf("can't create N3 client: %w", err) return fmt.Errorf("can't create N3 client: %w", err)
} }
@ -110,7 +111,7 @@ func dumpContractHashes(cmd *cobra.Command, _ []string) error {
return nil return nil
} }
func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string, c Client) error { func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string, c morphUtil.Client) error {
const nnsMaxTokens = 100 const nnsMaxTokens = 100
inv := invoker.New(c, nil) inv := invoker.New(c, nil)
@ -224,7 +225,7 @@ func printContractInfo(cmd *cobra.Command, infos []contractDumpInfo) {
cmd.Print(buf.String()) cmd.Print(buf.String())
} }
func fillContractVersion(cmd *cobra.Command, c Client, infos []contractDumpInfo) { func fillContractVersion(cmd *cobra.Command, c morphUtil.Client, infos []contractDumpInfo) {
bw := io.NewBufBinWriter() bw := io.NewBufBinWriter()
sub := io.NewBufBinWriter() sub := io.NewBufBinWriter()
for i := range infos { for i := range infos {

View file

@ -6,6 +6,7 @@ import (
"sort" "sort"
frostfsidclient "git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client" frostfsidclient "git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
@ -41,7 +42,7 @@ var (
Short: "Create new namespace in frostfsid contract", Short: "Create new namespace in frostfsid contract",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
}, },
Run: frostfsidCreateNamespace, Run: frostfsidCreateNamespace,
} }
@ -51,7 +52,7 @@ var (
Short: "List all namespaces in frostfsid", Short: "List all namespaces in frostfsid",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
}, },
Run: frostfsidListNamespaces, Run: frostfsidListNamespaces,
} }
@ -61,7 +62,7 @@ var (
Short: "Create subject in frostfsid contract", Short: "Create subject in frostfsid contract",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
}, },
Run: frostfsidCreateSubject, Run: frostfsidCreateSubject,
} }
@ -71,7 +72,7 @@ var (
Short: "Delete subject from frostfsid contract", Short: "Delete subject from frostfsid contract",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
}, },
Run: frostfsidDeleteSubject, Run: frostfsidDeleteSubject,
} }
@ -81,7 +82,7 @@ var (
Short: "List subjects in namespace", Short: "List subjects in namespace",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
}, },
Run: frostfsidListSubjects, Run: frostfsidListSubjects,
} }
@ -91,7 +92,7 @@ var (
Short: "Create group in frostfsid contract", Short: "Create group in frostfsid contract",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
}, },
Run: frostfsidCreateGroup, Run: frostfsidCreateGroup,
} }
@ -101,7 +102,7 @@ var (
Short: "Delete group from frostfsid contract", Short: "Delete group from frostfsid contract",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
}, },
Run: frostfsidDeleteGroup, Run: frostfsidDeleteGroup,
} }
@ -111,7 +112,7 @@ var (
Short: "List groups in namespace", Short: "List groups in namespace",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
}, },
Run: frostfsidListGroups, Run: frostfsidListGroups,
} }
@ -121,7 +122,7 @@ var (
Short: "Add subject to group", Short: "Add subject to group",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
}, },
Run: frostfsidAddSubjectToGroup, Run: frostfsidAddSubjectToGroup,
} }
@ -131,7 +132,7 @@ var (
Short: "Remove subject from group", Short: "Remove subject from group",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
}, },
Run: frostfsidRemoveSubjectFromGroup, Run: frostfsidRemoveSubjectFromGroup,
} }
@ -141,7 +142,7 @@ var (
Short: "List subjects in group", Short: "List subjects in group",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(morphUtil.EndpointFlag, cmd.Flags().Lookup(morphUtil.EndpointFlag))
}, },
Run: frostfsidListGroupSubjects, Run: frostfsidListGroupSubjects,
} }
@ -149,20 +150,20 @@ var (
func initFrostfsIDCreateNamespaceCmd() { func initFrostfsIDCreateNamespaceCmd() {
frostfsidCmd.AddCommand(frostfsidCreateNamespaceCmd) frostfsidCmd.AddCommand(frostfsidCreateNamespaceCmd)
frostfsidCreateNamespaceCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) frostfsidCreateNamespaceCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
frostfsidCreateNamespaceCmd.Flags().String(namespaceFlag, "", "Namespace name to create") frostfsidCreateNamespaceCmd.Flags().String(namespaceFlag, "", "Namespace name to create")
frostfsidCreateNamespaceCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) frostfsidCreateNamespaceCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
} }
func initFrostfsIDListNamespacesCmd() { func initFrostfsIDListNamespacesCmd() {
frostfsidCmd.AddCommand(frostfsidListNamespacesCmd) frostfsidCmd.AddCommand(frostfsidListNamespacesCmd)
frostfsidListNamespacesCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) frostfsidListNamespacesCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
frostfsidListNamespacesCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) frostfsidListNamespacesCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
} }
func initFrostfsIDCreateSubjectCmd() { func initFrostfsIDCreateSubjectCmd() {
frostfsidCmd.AddCommand(frostfsidCreateSubjectCmd) frostfsidCmd.AddCommand(frostfsidCreateSubjectCmd)
frostfsidCreateSubjectCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) frostfsidCreateSubjectCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
frostfsidCreateSubjectCmd.Flags().String(namespaceFlag, "", "Namespace where create subject") frostfsidCreateSubjectCmd.Flags().String(namespaceFlag, "", "Namespace where create subject")
frostfsidCreateSubjectCmd.Flags().String(subjectNameFlag, "", "Subject name, must be unique in namespace") frostfsidCreateSubjectCmd.Flags().String(subjectNameFlag, "", "Subject name, must be unique in namespace")
frostfsidCreateSubjectCmd.Flags().String(subjectKeyFlag, "", "Subject hex-encoded public key") frostfsidCreateSubjectCmd.Flags().String(subjectKeyFlag, "", "Subject hex-encoded public key")
@ -171,14 +172,14 @@ func initFrostfsIDCreateSubjectCmd() {
func initFrostfsIDDeleteSubjectCmd() { func initFrostfsIDDeleteSubjectCmd() {
frostfsidCmd.AddCommand(frostfsidDeleteSubjectCmd) frostfsidCmd.AddCommand(frostfsidDeleteSubjectCmd)
frostfsidDeleteSubjectCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) frostfsidDeleteSubjectCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
frostfsidDeleteSubjectCmd.Flags().String(subjectAddressFlag, "", "Subject address") frostfsidDeleteSubjectCmd.Flags().String(subjectAddressFlag, "", "Subject address")
frostfsidDeleteSubjectCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) frostfsidDeleteSubjectCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
} }
func initFrostfsIDListSubjectsCmd() { func initFrostfsIDListSubjectsCmd() {
frostfsidCmd.AddCommand(frostfsidListSubjectsCmd) frostfsidCmd.AddCommand(frostfsidListSubjectsCmd)
frostfsidListSubjectsCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) frostfsidListSubjectsCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
frostfsidListSubjectsCmd.Flags().String(namespaceFlag, "", "Namespace to list subjects") frostfsidListSubjectsCmd.Flags().String(namespaceFlag, "", "Namespace to list subjects")
frostfsidListSubjectsCmd.Flags().Bool(includeNamesFlag, false, "Whether include subject name (require additional requests)") frostfsidListSubjectsCmd.Flags().Bool(includeNamesFlag, false, "Whether include subject name (require additional requests)")
frostfsidListSubjectsCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) frostfsidListSubjectsCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
@ -186,7 +187,7 @@ func initFrostfsIDListSubjectsCmd() {
func initFrostfsIDCreateGroupCmd() { func initFrostfsIDCreateGroupCmd() {
frostfsidCmd.AddCommand(frostfsidCreateGroupCmd) frostfsidCmd.AddCommand(frostfsidCreateGroupCmd)
frostfsidCreateGroupCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) frostfsidCreateGroupCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
frostfsidCreateGroupCmd.Flags().String(namespaceFlag, "", "Namespace where create group") frostfsidCreateGroupCmd.Flags().String(namespaceFlag, "", "Namespace where create group")
frostfsidCreateGroupCmd.Flags().String(groupNameFlag, "", "Group name, must be unique in namespace") frostfsidCreateGroupCmd.Flags().String(groupNameFlag, "", "Group name, must be unique in namespace")
frostfsidCreateGroupCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) frostfsidCreateGroupCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
@ -194,7 +195,7 @@ func initFrostfsIDCreateGroupCmd() {
func initFrostfsIDDeleteGroupCmd() { func initFrostfsIDDeleteGroupCmd() {
frostfsidCmd.AddCommand(frostfsidDeleteGroupCmd) frostfsidCmd.AddCommand(frostfsidDeleteGroupCmd)
frostfsidDeleteGroupCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) frostfsidDeleteGroupCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
frostfsidDeleteGroupCmd.Flags().String(namespaceFlag, "", "Namespace to delete group") frostfsidDeleteGroupCmd.Flags().String(namespaceFlag, "", "Namespace to delete group")
frostfsidDeleteGroupCmd.Flags().Int64(groupIDFlag, 0, "Group id") frostfsidDeleteGroupCmd.Flags().Int64(groupIDFlag, 0, "Group id")
frostfsidDeleteGroupCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) frostfsidDeleteGroupCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
@ -202,14 +203,14 @@ func initFrostfsIDDeleteGroupCmd() {
func initFrostfsIDListGroupsCmd() { func initFrostfsIDListGroupsCmd() {
frostfsidCmd.AddCommand(frostfsidListGroupsCmd) frostfsidCmd.AddCommand(frostfsidListGroupsCmd)
frostfsidListGroupsCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) frostfsidListGroupsCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
frostfsidListGroupsCmd.Flags().String(namespaceFlag, "", "Namespace to list groups") frostfsidListGroupsCmd.Flags().String(namespaceFlag, "", "Namespace to list groups")
frostfsidListGroupsCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) frostfsidListGroupsCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
} }
func initFrostfsIDAddSubjectToGroupCmd() { func initFrostfsIDAddSubjectToGroupCmd() {
frostfsidCmd.AddCommand(frostfsidAddSubjectToGroupCmd) frostfsidCmd.AddCommand(frostfsidAddSubjectToGroupCmd)
frostfsidAddSubjectToGroupCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) frostfsidAddSubjectToGroupCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
frostfsidAddSubjectToGroupCmd.Flags().String(subjectAddressFlag, "", "Subject address") frostfsidAddSubjectToGroupCmd.Flags().String(subjectAddressFlag, "", "Subject address")
frostfsidAddSubjectToGroupCmd.Flags().Int64(groupIDFlag, 0, "Group id") frostfsidAddSubjectToGroupCmd.Flags().Int64(groupIDFlag, 0, "Group id")
frostfsidAddSubjectToGroupCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) frostfsidAddSubjectToGroupCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
@ -217,7 +218,7 @@ func initFrostfsIDAddSubjectToGroupCmd() {
func initFrostfsIDRemoveSubjectFromGroupCmd() { func initFrostfsIDRemoveSubjectFromGroupCmd() {
frostfsidCmd.AddCommand(frostfsidRemoveSubjectFromGroupCmd) frostfsidCmd.AddCommand(frostfsidRemoveSubjectFromGroupCmd)
frostfsidRemoveSubjectFromGroupCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) frostfsidRemoveSubjectFromGroupCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
frostfsidRemoveSubjectFromGroupCmd.Flags().String(subjectAddressFlag, "", "Subject address") frostfsidRemoveSubjectFromGroupCmd.Flags().String(subjectAddressFlag, "", "Subject address")
frostfsidRemoveSubjectFromGroupCmd.Flags().Int64(groupIDFlag, 0, "Group id") frostfsidRemoveSubjectFromGroupCmd.Flags().Int64(groupIDFlag, 0, "Group id")
frostfsidRemoveSubjectFromGroupCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) frostfsidRemoveSubjectFromGroupCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
@ -225,7 +226,7 @@ func initFrostfsIDRemoveSubjectFromGroupCmd() {
func initFrostfsIDListGroupSubjectsCmd() { func initFrostfsIDListGroupSubjectsCmd() {
frostfsidCmd.AddCommand(frostfsidListGroupSubjectsCmd) frostfsidCmd.AddCommand(frostfsidListGroupSubjectsCmd)
frostfsidListGroupSubjectsCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) frostfsidListGroupSubjectsCmd.Flags().StringP(morphUtil.EndpointFlag, morphUtil.EndpointFlagShort, "", morphUtil.EndpointFlagDesc)
frostfsidListGroupSubjectsCmd.Flags().String(namespaceFlag, "", "Namespace name") frostfsidListGroupSubjectsCmd.Flags().String(namespaceFlag, "", "Namespace name")
frostfsidListGroupSubjectsCmd.Flags().Int64(groupIDFlag, 0, "Group id") frostfsidListGroupSubjectsCmd.Flags().Int64(groupIDFlag, 0, "Group id")
frostfsidListGroupSubjectsCmd.Flags().Bool(includeNamesFlag, false, "Whether include subject name (require additional requests)") frostfsidListGroupSubjectsCmd.Flags().Bool(includeNamesFlag, false, "Whether include subject name (require additional requests)")
@ -467,5 +468,5 @@ func (f *frostfsidClient) sendWaitRes() (*state.AppExecResult, error) {
} }
f.wCtx.Command.Println("Waiting for transactions to persist...") f.wCtx.Command.Println("Waiting for transactions to persist...")
return f.roCli.Wait(f.wCtx.SentTxs[0].hash, f.wCtx.SentTxs[0].vub, nil) return f.roCli.Wait(f.wCtx.SentTxs[0].Hash, f.wCtx.SentTxs[0].Vub, nil)
} }

View file

@ -7,6 +7,7 @@ import (
"path/filepath" "path/filepath"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
@ -27,7 +28,6 @@ import (
const ( const (
singleAccountName = "single" singleAccountName = "single"
committeeAccountName = "committee" committeeAccountName = "committee"
consensusAccountName = "consensus"
) )
func generateAlphabetCreds(cmd *cobra.Command, _ []string) error { func generateAlphabetCreds(cmd *cobra.Command, _ []string) error {
@ -39,8 +39,8 @@ func generateAlphabetCreds(cmd *cobra.Command, _ []string) error {
if size == 0 { if size == 0 {
return errors.New("size must be > 0") return errors.New("size must be > 0")
} }
if size > maxAlphabetNodes { if size > morphUtil.MaxAlphabetNodes {
return ErrTooManyAlphabetNodes return morphUtil.ErrTooManyAlphabetNodes
} }
v := viper.GetViper() v := viper.GetViper()
@ -109,7 +109,7 @@ func initializeWallets(v *viper.Viper, walletDir string, size int) ([]string, er
if err := addMultisigAccount(wallets[i], majCount, committeeAccountName, passwords[i], ps); err != nil { if err := addMultisigAccount(wallets[i], majCount, committeeAccountName, passwords[i], ps); err != nil {
return fmt.Errorf("can't create committee account: %w", err) return fmt.Errorf("can't create committee account: %w", err)
} }
if err := addMultisigAccount(wallets[i], bftCount, consensusAccountName, passwords[i], ps); err != nil { if err := addMultisigAccount(wallets[i], bftCount, morphUtil.ConsensusAccountName, passwords[i], ps); err != nil {
return fmt.Errorf("can't create consentus account: %w", err) return fmt.Errorf("can't create consentus account: %w", err)
} }
if err := wallets[i].SavePretty(); err != nil { if err := wallets[i].SavePretty(); err != nil {

View file

@ -10,6 +10,7 @@ import (
"sync" "sync"
"testing" "testing"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
"github.com/nspcc-dev/neo-go/cli/input" "github.com/nspcc-dev/neo-go/cli/input"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
@ -87,7 +88,7 @@ func TestGenerateAlphabet(t *testing.T) {
err := a.Decrypt(strconv.FormatUint(i, 10), keys.NEP2ScryptParams()) err := a.Decrypt(strconv.FormatUint(i, 10), keys.NEP2ScryptParams())
require.NoError(t, err, "can't decrypt account") require.NoError(t, err, "can't decrypt account")
switch a.Label { switch a.Label {
case consensusAccountName: case util.ConsensusAccountName:
require.Equal(t, smartcontract.GetDefaultHonestNodeCount(size), len(a.Contract.Parameters)) require.Equal(t, smartcontract.GetDefaultHonestNodeCount(size), len(a.Contract.Parameters))
case committeeAccountName: case committeeAccountName:
require.Equal(t, smartcontract.GetMajorityHonestNodeCount(size), len(a.Contract.Parameters)) require.Equal(t, smartcontract.GetMajorityHonestNodeCount(size), len(a.Contract.Parameters))

View file

@ -4,10 +4,9 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client" morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" "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/state"
@ -15,28 +14,19 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/management" "github.com/nspcc-dev/neo-go/pkg/rpcclient/management"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
"github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
const (
// maxAlphabetNodes is the maximum number of candidates allowed, which is currently limited by the size
// of the invocation script.
// See: https://github.com/nspcc-dev/neo-go/blob/740488f7f35e367eaa99a71c0a609c315fe2b0fc/pkg/core/transaction/witness.go#L10
maxAlphabetNodes = 22
)
type cache struct { type cache struct {
nnsCs *state.Contract nnsCs *state.Contract
groupKey *keys.PublicKey groupKey *keys.PublicKey
} }
type initializeContext struct { type initializeContext struct {
clientContext morphUtil.ClientContext
cache cache
// CommitteeAcc is used for retrieving the committee address and the verification script. // CommitteeAcc is used for retrieving the committee address and the verification script.
CommitteeAcc *wallet.Account CommitteeAcc *wallet.Account
@ -53,8 +43,6 @@ type initializeContext struct {
ContractURL string ContractURL string
} }
var ErrTooManyAlphabetNodes = fmt.Errorf("too many alphabet nodes (maximum allowed is %d)", maxAlphabetNodes)
func initializeSideChainCmd(cmd *cobra.Command, _ []string) error { func initializeSideChainCmd(cmd *cobra.Command, _ []string) error {
initCtx, err := newInitializeContext(cmd, viper.GetViper()) initCtx, err := newInitializeContext(cmd, viper.GetViper())
if err != nil { if err != nil {
@ -105,8 +93,8 @@ func initializeSideChainCmd(cmd *cobra.Command, _ []string) error {
} }
func (c *initializeContext) close() { func (c *initializeContext) close() {
if local, ok := c.Client.(*localClient); ok { if local, ok := c.Client.(*morphUtil.LocalClient); ok {
err := local.dump() err := local.Dump()
if err != nil { if err != nil {
c.Command.PrintErrf("Can't write dump: %v\n", err) c.Command.PrintErrf("Can't write dump: %v\n", err)
os.Exit(1) os.Exit(1)
@ -116,7 +104,7 @@ func (c *initializeContext) close() {
func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContext, error) { func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContext, error) {
walletDir := config.ResolveHomePath(viper.GetString(alphabetWalletsFlag)) walletDir := config.ResolveHomePath(viper.GetString(alphabetWalletsFlag))
wallets, err := getAlphabetWallets(v, walletDir) wallets, err := morphUtil.GetAlphabetWallets(v, walletDir)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -134,12 +122,12 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
return nil, err return nil, err
} }
committeeAcc, err := getWalletAccount(wallets[0], committeeAccountName) committeeAcc, err := morphUtil.GetWalletAccount(wallets[0], committeeAccountName)
if err != nil { if err != nil {
return nil, fmt.Errorf("can't find committee account: %w", err) return nil, fmt.Errorf("can't find committee account: %w", err)
} }
consensusAcc, err := getWalletAccount(wallets[0], consensusAccountName) consensusAcc, err := morphUtil.GetWalletAccount(wallets[0], morphUtil.ConsensusAccountName)
if err != nil { if err != nil {
return nil, fmt.Errorf("can't find consensus account: %w", err) return nil, fmt.Errorf("can't find consensus account: %w", err)
} }
@ -167,13 +155,13 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
return nil, err return nil, err
} }
cliCtx, err := defaultClientContext(c, committeeAcc) cliCtx, err := morphUtil.DefaultClientContext(c, committeeAcc)
if err != nil { if err != nil {
return nil, fmt.Errorf("client context: %w", err) return nil, fmt.Errorf("client context: %w", err)
} }
initCtx := &initializeContext{ initCtx := &initializeContext{
clientContext: *cliCtx, ClientContext: *cliCtx,
ConsensusAcc: consensusAcc, ConsensusAcc: consensusAcc,
CommitteeAcc: committeeAcc, CommitteeAcc: committeeAcc,
ContractWallet: w, ContractWallet: w,
@ -210,16 +198,16 @@ func validateInit(cmd *cobra.Command) error {
return nil return nil
} }
func createClient(cmd *cobra.Command, v *viper.Viper, wallets []*wallet.Wallet) (Client, error) { func createClient(cmd *cobra.Command, v *viper.Viper, wallets []*wallet.Wallet) (morphUtil.Client, error) {
var c Client var c morphUtil.Client
var err error var err error
if ldf := cmd.Flags().Lookup(localDumpFlag); ldf != nil && ldf.Changed { if ldf := cmd.Flags().Lookup(localDumpFlag); ldf != nil && ldf.Changed {
if cmd.Flags().Changed(endpointFlag) { if cmd.Flags().Changed(morphUtil.EndpointFlag) {
return nil, fmt.Errorf("`%s` and `%s` flags are mutually exclusive", endpointFlag, localDumpFlag) return nil, fmt.Errorf("`%s` and `%s` flags are mutually exclusive", morphUtil.EndpointFlag, localDumpFlag)
} }
c, err = newLocalClient(cmd, v, wallets, ldf.Value.String()) c, err = morphUtil.NewLocalClient(cmd, v, wallets, ldf.Value.String())
} else { } else {
c, err = getN3Client(v) c, err = morphUtil.GetN3Client(v)
} }
if err != nil { if err != nil {
return nil, fmt.Errorf("can't create N3 client: %w", err) return nil, fmt.Errorf("can't create N3 client: %w", err)
@ -249,7 +237,7 @@ func getContractsPath(cmd *cobra.Command, needContracts bool) (string, error) {
func createWalletAccounts(wallets []*wallet.Wallet) ([]*wallet.Account, error) { func createWalletAccounts(wallets []*wallet.Wallet) ([]*wallet.Account, error) {
accounts := make([]*wallet.Account, len(wallets)) accounts := make([]*wallet.Account, len(wallets))
for i, w := range wallets { for i, w := range wallets {
acc, err := getWalletAccount(w, singleAccountName) acc, err := morphUtil.GetWalletAccount(w, singleAccountName)
if err != nil { if err != nil {
return nil, fmt.Errorf("wallet %s is invalid (no single account): %w", w.Path(), err) return nil, fmt.Errorf("wallet %s is invalid (no single account): %w", w.Path(), err)
} }
@ -259,7 +247,7 @@ func createWalletAccounts(wallets []*wallet.Wallet) ([]*wallet.Account, error) {
} }
func (c *initializeContext) awaitTx() error { func (c *initializeContext) awaitTx() error {
return c.clientContext.awaitTx(c.Command) return c.ClientContext.AwaitTx(c.Command)
} }
func (c *initializeContext) nnsContractState() (*state.Contract, error) { func (c *initializeContext) nnsContractState() (*state.Contract, error) {
@ -310,89 +298,6 @@ func (c *initializeContext) getSigner(tryGroup bool, acc *wallet.Account) transa
return signer return signer
} }
func (c *clientContext) awaitTx(cmd *cobra.Command) error {
if len(c.SentTxs) == 0 {
return nil
}
if local, ok := c.Client.(*localClient); ok {
if err := local.putTransactions(); err != nil {
return fmt.Errorf("can't persist transactions: %w", err)
}
}
err := awaitTx(cmd, c.Client, c.SentTxs)
c.SentTxs = c.SentTxs[:0]
return err
}
func awaitTx(cmd *cobra.Command, c Client, txs []hashVUBPair) error {
cmd.Println("Waiting for transactions to persist...")
at := trigger.Application
var retErr error
loop:
for i := range txs {
var it int
var pollInterval time.Duration
var pollIntervalChanged bool
for {
// We must fetch current height before application log, to avoid race condition.
currBlock, err := c.GetBlockCount()
if err != nil {
return fmt.Errorf("can't fetch current block height: %w", err)
}
res, err := c.GetApplicationLog(txs[i].hash, &at)
if err == nil {
if retErr == nil && len(res.Executions) > 0 && res.Executions[0].VMState != vmstate.Halt {
retErr = fmt.Errorf("tx %d persisted in %s state: %s",
i, res.Executions[0].VMState, res.Executions[0].FaultException)
}
continue loop
}
if txs[i].vub < currBlock {
return fmt.Errorf("tx was not persisted: vub=%d, height=%d", txs[i].vub, currBlock)
}
pollInterval, pollIntervalChanged = nextPollInterval(it, pollInterval)
if pollIntervalChanged && viper.GetBool(commonflags.Verbose) {
cmd.Printf("Pool interval to check transaction persistence changed: %s\n", pollInterval.String())
}
timer := time.NewTimer(pollInterval)
select {
case <-cmd.Context().Done():
return cmd.Context().Err()
case <-timer.C:
}
it++
}
}
return retErr
}
func nextPollInterval(it int, previous time.Duration) (time.Duration, bool) {
const minPollInterval = 1 * time.Second
const maxPollInterval = 16 * time.Second
const changeAfter = 5
if it == 0 {
return minPollInterval, true
}
if it%changeAfter != 0 {
return previous, false
}
nextInterval := previous * 2
if nextInterval > maxPollInterval {
return maxPollInterval, previous != maxPollInterval
}
return nextInterval, true
}
// sendCommitteeTx creates transaction from script, signs it by committee nodes and sends it to RPC. // sendCommitteeTx creates transaction from script, signs it by committee nodes and sends it to RPC.
// If tryGroup is false, global scope is used for the signer (useful when // If tryGroup is false, global scope is used for the signer (useful when
// working with native contracts). // working with native contracts).
@ -445,24 +350,15 @@ func (c *initializeContext) sendMultiTx(script []byte, tryGroup bool, withConsen
return err return err
} }
if withConsensus { if withConsensus {
if err := c.multiSign(tx, consensusAccountName); err != nil { if err := c.multiSign(tx, morphUtil.ConsensusAccountName); err != nil {
return err return err
} }
} }
return c.sendTx(tx, c.Command, false) return c.SendTx(tx, c.Command, false)
} }
func getWalletAccount(w *wallet.Wallet, typ string) (*wallet.Account, error) { func checkNotaryEnabled(c morphUtil.Client) error {
for i := range w.Accounts {
if w.Accounts[i].Label == typ {
return w.Accounts[i], nil
}
}
return nil, fmt.Errorf("account for '%s' not found", typ)
}
func checkNotaryEnabled(c Client) error {
ns, err := c.GetNativeContracts() ns, err := c.GetNativeContracts()
if err != nil { if err != nil {
return fmt.Errorf("can't get native contract hashes: %w", err) return fmt.Errorf("can't get native contract hashes: %w", err)

View file

@ -14,6 +14,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-contract/common" "git.frostfs.info/TrueCloudLab/frostfs-contract/common"
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns" "git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client" morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
@ -332,7 +333,7 @@ func (c *initializeContext) deployContracts() error {
return fmt.Errorf("can't deploy alphabet #%d contract: %w", i, err) return fmt.Errorf("can't deploy alphabet #%d contract: %w", i, err)
} }
c.SentTxs = append(c.SentTxs, hashVUBPair{hash: txHash, vub: vub}) c.SentTxs = append(c.SentTxs, morphUtil.HashVUBPair{Hash: txHash, Vub: vub})
} }
for _, ctrName := range contractList { for _, ctrName := range contractList {

View file

@ -8,6 +8,7 @@ import (
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns" "git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client" morphClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
@ -288,14 +289,14 @@ func parseNNSResolveResult(res stackitem.Item) (util.Uint160, error) {
return util.Uint160{}, errors.New("no valid hashes are found") return util.Uint160{}, errors.New("no valid hashes are found")
} }
func nnsIsAvailable(c Client, nnsHash util.Uint160, name string) (bool, error) { func nnsIsAvailable(c morphUtil.Client, nnsHash util.Uint160, name string) (bool, error) {
switch c.(type) { switch c.(type) {
case *rpcclient.Client: case *rpcclient.Client:
inv := invoker.New(c, nil) inv := invoker.New(c, nil)
reader := nnsClient.NewReader(inv, nnsHash) reader := nnsClient.NewReader(inv, nnsHash)
return reader.IsAvailable(name) return reader.IsAvailable(name)
default: default:
b, err := unwrap.Bool(invokeFunction(c, nnsHash, "isAvailable", []any{name}, nil)) b, err := unwrap.Bool(morphUtil.InvokeFunction(c, nnsHash, "isAvailable", []any{name}, nil))
if err != nil { if err != nil {
return false, fmt.Errorf("`isAvailable`: invalid response: %w", err) return false, fmt.Errorf("`isAvailable`: invalid response: %w", err)
} }

View file

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"math/big" "math/big"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
"github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/nspcc-dev/neo-go/pkg/core/native"
"github.com/nspcc-dev/neo-go/pkg/core/state" "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/core/transaction"
@ -78,7 +79,7 @@ func (c *initializeContext) registerCandidateRange(start, end int) error {
} }
} }
return c.sendTx(tx, c.Command, true) return c.SendTx(tx, c.Command, true)
} }
func (c *initializeContext) registerCandidates() error { func (c *initializeContext) registerCandidates() error {
@ -156,7 +157,7 @@ func (c *initializeContext) getCandidateRegisterPrice() (int64, error) {
return reader.GetRegisterPrice() return reader.GetRegisterPrice()
default: default:
neoHash := neo.Hash neoHash := neo.Hash
res, err := invokeFunction(c.Client, neoHash, "getRegisterPrice", nil, nil) res, err := morphUtil.InvokeFunction(c.Client, neoHash, "getRegisterPrice", nil, nil)
if err != nil { if err != nil {
return 0, err return 0, err
} }

View file

@ -1,6 +1,7 @@
package morph package morph
import ( import (
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles" "github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/rolemgmt" "github.com/nspcc-dev/neo-go/pkg/rpcclient/rolemgmt"
@ -40,6 +41,6 @@ func (c *initializeContext) setRolesFinished() (bool, error) {
return false, err return false, err
} }
pubs, err := getDesignatedByRole(c.ReadOnlyInvoker, rolemgmt.Hash, noderoles.NeoFSAlphabet, height) pubs, err := util.GetDesignatedByRole(c.ReadOnlyInvoker, rolemgmt.Hash, noderoles.NeoFSAlphabet, height)
return len(pubs) == len(c.Wallets), err return len(pubs) == len(c.Wallets), err
} }

View file

@ -9,6 +9,7 @@ import (
"testing" "testing"
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
@ -42,10 +43,10 @@ func TestInitialize(t *testing.T) {
testInitialize(t, 16) testInitialize(t, 16)
}) })
t.Run("max nodes", func(t *testing.T) { t.Run("max nodes", func(t *testing.T) {
testInitialize(t, maxAlphabetNodes) testInitialize(t, util.MaxAlphabetNodes)
}) })
t.Run("too many nodes", func(t *testing.T) { t.Run("too many nodes", func(t *testing.T) {
require.ErrorIs(t, generateTestData(t, t.TempDir(), maxAlphabetNodes+1), ErrTooManyAlphabetNodes) require.ErrorIs(t, generateTestData(t, t.TempDir(), util.MaxAlphabetNodes+1), util.ErrTooManyAlphabetNodes)
}) })
} }
@ -54,7 +55,7 @@ func testInitialize(t *testing.T, committeeSize int) {
v := viper.GetViper() v := viper.GetViper()
require.NoError(t, generateTestData(t, testdataDir, committeeSize)) require.NoError(t, generateTestData(t, testdataDir, committeeSize))
v.Set(protoConfigPath, filepath.Join(testdataDir, protoFileName)) v.Set(util.ProtoConfigPath, filepath.Join(testdataDir, protoFileName))
// Set to the path or remove the next statement to download from the network. // Set to the path or remove the next statement to download from the network.
require.NoError(t, initCmd.Flags().Set(contractsInitFlag, contractsPath)) require.NoError(t, initCmd.Flags().Set(contractsInitFlag, contractsPath))
@ -150,33 +151,33 @@ func TestNextPollInterval(t *testing.T) {
var pollInterval time.Duration var pollInterval time.Duration
var iteration int var iteration int
pollInterval, hasChanged := nextPollInterval(iteration, pollInterval) pollInterval, hasChanged := util.NextPollInterval(iteration, pollInterval)
require.True(t, hasChanged) require.True(t, hasChanged)
require.Equal(t, time.Second, pollInterval) require.Equal(t, time.Second, pollInterval)
iteration = 4 iteration = 4
pollInterval, hasChanged = nextPollInterval(iteration, pollInterval) pollInterval, hasChanged = util.NextPollInterval(iteration, pollInterval)
require.False(t, hasChanged) require.False(t, hasChanged)
require.Equal(t, time.Second, pollInterval) require.Equal(t, time.Second, pollInterval)
iteration = 5 iteration = 5
pollInterval, hasChanged = nextPollInterval(iteration, pollInterval) pollInterval, hasChanged = util.NextPollInterval(iteration, pollInterval)
require.True(t, hasChanged) require.True(t, hasChanged)
require.Equal(t, 2*time.Second, pollInterval) require.Equal(t, 2*time.Second, pollInterval)
iteration = 10 iteration = 10
pollInterval, hasChanged = nextPollInterval(iteration, pollInterval) pollInterval, hasChanged = util.NextPollInterval(iteration, pollInterval)
require.True(t, hasChanged) require.True(t, hasChanged)
require.Equal(t, 4*time.Second, pollInterval) require.Equal(t, 4*time.Second, pollInterval)
iteration = 20 iteration = 20
pollInterval = 32 * time.Second pollInterval = 32 * time.Second
pollInterval, hasChanged = nextPollInterval(iteration, pollInterval) pollInterval, hasChanged = util.NextPollInterval(iteration, pollInterval)
require.True(t, hasChanged) // from 32s to 16s require.True(t, hasChanged) // from 32s to 16s
require.Equal(t, 16*time.Second, pollInterval) require.Equal(t, 16*time.Second, pollInterval)
pollInterval = 16 * time.Second pollInterval = 16 * time.Second
pollInterval, hasChanged = nextPollInterval(iteration, pollInterval) pollInterval, hasChanged = util.NextPollInterval(iteration, pollInterval)
require.False(t, hasChanged) require.False(t, hasChanged)
require.Equal(t, 16*time.Second, pollInterval) require.Equal(t, 16*time.Second, pollInterval)
} }

View file

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"math/big" "math/big"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
"github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/nspcc-dev/neo-go/pkg/core/native"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
@ -67,7 +68,7 @@ func (c *initializeContext) transferFunds() error {
return fmt.Errorf("can't create transfer transaction: %w", err) return fmt.Errorf("can't create transfer transaction: %w", err)
} }
if err := c.multiSignAndSend(tx, consensusAccountName); err != nil { if err := c.multiSignAndSend(tx, morphUtil.ConsensusAccountName); err != nil {
return fmt.Errorf("can't send transfer transaction: %w", err) return fmt.Errorf("can't send transfer transaction: %w", err)
} }
@ -87,7 +88,7 @@ func (c *initializeContext) multiSignAndSend(tx *transaction.Transaction, accTyp
return err return err
} }
return c.sendTx(tx, c.Command, false) return c.SendTx(tx, c.Command, false)
} }
func (c *initializeContext) multiSign(tx *transaction.Transaction, accType string) error { func (c *initializeContext) multiSign(tx *transaction.Transaction, accType string) error {
@ -102,11 +103,11 @@ func (c *initializeContext) multiSign(tx *transaction.Transaction, accType strin
// Use parameter context to avoid dealing with signature order. // Use parameter context to avoid dealing with signature order.
pc := scContext.NewParameterContext("", network, tx) pc := scContext.NewParameterContext("", network, tx)
h := c.CommitteeAcc.Contract.ScriptHash() h := c.CommitteeAcc.Contract.ScriptHash()
if accType == consensusAccountName { if accType == morphUtil.ConsensusAccountName {
h = c.ConsensusAcc.Contract.ScriptHash() h = c.ConsensusAcc.Contract.ScriptHash()
} }
for _, w := range c.Wallets { for _, w := range c.Wallets {
acc, err := getWalletAccount(w, accType) acc, err := morphUtil.GetWalletAccount(w, accType)
if err != nil { if err != nil {
return fmt.Errorf("can't find %s wallet account: %w", accType, err) return fmt.Errorf("can't find %s wallet account: %w", accType, err)
} }
@ -174,7 +175,7 @@ type transferTarget struct {
Data any Data any
} }
func createNEP17MultiTransferTx(c Client, acc *wallet.Account, recipients []transferTarget) (*transaction.Transaction, error) { func createNEP17MultiTransferTx(c morphUtil.Client, acc *wallet.Account, recipients []transferTarget) (*transaction.Transaction, error) {
from := acc.Contract.ScriptHash() from := acc.Contract.ScriptHash()
w := io.NewBufBinWriter() w := io.NewBufBinWriter()

View file

@ -2,6 +2,7 @@ package morph
import ( import (
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker" "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
@ -11,7 +12,7 @@ import (
) )
func listNetmapCandidatesNodes(cmd *cobra.Command, _ []string) { func listNetmapCandidatesNodes(cmd *cobra.Command, _ []string) {
c, err := getN3Client(viper.GetViper()) c, err := util.GetN3Client(viper.GetViper())
commonCmd.ExitOnErr(cmd, "can't create N3 client: %w", err) commonCmd.ExitOnErr(cmd, "can't create N3 client: %w", err)
inv := invoker.New(c, nil) inv := invoker.New(c, nil)

View file

@ -5,6 +5,7 @@ import (
"math/big" "math/big"
"strconv" "strconv"
morphUtil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
"github.com/nspcc-dev/neo-go/cli/input" "github.com/nspcc-dev/neo-go/cli/input"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "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/crypto/keys"
@ -79,7 +80,7 @@ func depositNotary(cmd *cobra.Command, _ []string) error {
} }
func transferGas(cmd *cobra.Command, acc *wallet.Account, accHash util.Uint160, gasAmount fixedn.Fixed8, till int64) error { func transferGas(cmd *cobra.Command, acc *wallet.Account, accHash util.Uint160, gasAmount fixedn.Fixed8, till int64) error {
c, err := getN3Client(viper.GetViper()) c, err := morphUtil.GetN3Client(viper.GetViper())
if err != nil { if err != nil {
return err return err
} }
@ -116,7 +117,7 @@ func transferGas(cmd *cobra.Command, acc *wallet.Account, accHash util.Uint160,
return fmt.Errorf("could not send tx: %w", err) return fmt.Errorf("could not send tx: %w", err)
} }
return awaitTx(cmd, c, []hashVUBPair{{hash: txHash, vub: vub}}) return morphUtil.AwaitTx(cmd, c, []morphUtil.HashVUBPair{{Hash: txHash, Vub: vub}})
} }
func openWallet(cmd *cobra.Command) (*wallet.Wallet, error) { func openWallet(cmd *cobra.Command) (*wallet.Wallet, error) {

View file

@ -7,6 +7,7 @@ import (
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker" "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
@ -58,7 +59,7 @@ func setPolicyCmd(cmd *cobra.Command, args []string) error {
} }
func dumpPolicyCmd(cmd *cobra.Command, _ []string) error { func dumpPolicyCmd(cmd *cobra.Command, _ []string) error {
c, err := getN3Client(viper.GetViper()) c, err := util.GetN3Client(viper.GetViper())
commonCmd.ExitOnErr(cmd, "can't create N3 client:", err) commonCmd.ExitOnErr(cmd, "can't create N3 client:", err)
inv := invoker.New(c, nil) inv := invoker.New(c, nil)

View file

@ -1,6 +1,7 @@
package morph package morph
import ( import (
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -9,9 +10,6 @@ const (
alphabetWalletsFlag = "alphabet-wallets" alphabetWalletsFlag = "alphabet-wallets"
alphabetWalletsFlagDesc = "Path to alphabet wallets dir" alphabetWalletsFlagDesc = "Path to alphabet wallets dir"
alphabetSizeFlag = "size" alphabetSizeFlag = "size"
endpointFlag = "rpc-endpoint"
endpointFlagDesc = "N3 RPC node endpoint"
endpointFlagShort = "r"
storageWalletFlag = "storage-wallet" storageWalletFlag = "storage-wallet"
storageWalletLabelFlag = "label" storageWalletLabelFlag = "label"
storageGasCLIFlag = "initial-gas" storageGasCLIFlag = "initial-gas"
@ -42,7 +40,7 @@ const (
walletAccountFlag = "account" walletAccountFlag = "account"
notaryDepositTillFlag = "till" notaryDepositTillFlag = "till"
localDumpFlag = "local-dump" localDumpFlag = "local-dump"
protoConfigPath = "protocol"
walletAddressFlag = "wallet-address" walletAddressFlag = "wallet-address"
) )
@ -68,7 +66,7 @@ var (
Short: "Initialize side chain network with smart-contracts and network settings", Short: "Initialize side chain network with smart-contracts and network settings",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
_ = viper.BindPFlag(epochDurationInitFlag, cmd.Flags().Lookup(epochDurationCLIFlag)) _ = viper.BindPFlag(epochDurationInitFlag, cmd.Flags().Lookup(epochDurationCLIFlag))
_ = viper.BindPFlag(maxObjectSizeInitFlag, cmd.Flags().Lookup(maxObjectSizeCLIFlag)) _ = viper.BindPFlag(maxObjectSizeInitFlag, cmd.Flags().Lookup(maxObjectSizeCLIFlag))
_ = viper.BindPFlag(homomorphicHashDisabledInitFlag, cmd.Flags().Lookup(homomorphicHashDisabledCLIFlag)) _ = viper.BindPFlag(homomorphicHashDisabledInitFlag, cmd.Flags().Lookup(homomorphicHashDisabledCLIFlag))
@ -76,7 +74,7 @@ var (
_ = viper.BindPFlag(containerFeeInitFlag, cmd.Flags().Lookup(containerFeeCLIFlag)) _ = viper.BindPFlag(containerFeeInitFlag, cmd.Flags().Lookup(containerFeeCLIFlag))
_ = viper.BindPFlag(containerAliasFeeInitFlag, cmd.Flags().Lookup(containerAliasFeeCLIFlag)) _ = viper.BindPFlag(containerAliasFeeInitFlag, cmd.Flags().Lookup(containerAliasFeeCLIFlag))
_ = viper.BindPFlag(withdrawFeeInitFlag, cmd.Flags().Lookup(withdrawFeeCLIFlag)) _ = viper.BindPFlag(withdrawFeeInitFlag, cmd.Flags().Lookup(withdrawFeeCLIFlag))
_ = viper.BindPFlag(protoConfigPath, cmd.Flags().Lookup(protoConfigPath)) _ = viper.BindPFlag(util.ProtoConfigPath, cmd.Flags().Lookup(util.ProtoConfigPath))
}, },
RunE: initializeSideChainCmd, RunE: initializeSideChainCmd,
} }
@ -86,7 +84,7 @@ var (
Short: "Generate storage node wallet for the morph network", Short: "Generate storage node wallet for the morph network",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
_ = viper.BindPFlag(storageGasConfigFlag, cmd.Flags().Lookup(storageGasCLIFlag)) _ = viper.BindPFlag(storageGasConfigFlag, cmd.Flags().Lookup(storageGasCLIFlag))
}, },
RunE: generateStorageCreds, RunE: generateStorageCreds,
@ -97,7 +95,7 @@ var (
Short: "Refill GAS of storage node's wallet in the morph network", Short: "Refill GAS of storage node's wallet in the morph network",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
_ = viper.BindPFlag(refillGasAmountFlag, cmd.Flags().Lookup(refillGasAmountFlag)) _ = viper.BindPFlag(refillGasAmountFlag, cmd.Flags().Lookup(refillGasAmountFlag))
}, },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
@ -110,7 +108,7 @@ var (
Short: "Create new FrostFS epoch event in the side chain", Short: "Create new FrostFS epoch event in the side chain",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: forceNewEpochCmd, RunE: forceNewEpochCmd,
} }
@ -121,7 +119,7 @@ var (
Long: `Move nodes to the Offline state in the candidates list and tick an epoch to update the netmap`, Long: `Move nodes to the Offline state in the candidates list and tick an epoch to update the netmap`,
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: removeNodesCmd, RunE: removeNodesCmd,
} }
@ -132,7 +130,7 @@ var (
Short: "Add/update global config value in the FrostFS network", Short: "Add/update global config value in the FrostFS network",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
RunE: setConfigCmd, RunE: setConfigCmd,
@ -144,7 +142,7 @@ var (
Short: "Set global policy values", Short: "Set global policy values",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: setPolicyCmd, RunE: setPolicyCmd,
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
@ -156,7 +154,7 @@ var (
Use: "dump-policy", Use: "dump-policy",
Short: "Dump FrostFS policy", Short: "Dump FrostFS policy",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: dumpPolicyCmd, RunE: dumpPolicyCmd,
} }
@ -165,7 +163,7 @@ var (
Use: "dump-hashes", Use: "dump-hashes",
Short: "Dump deployed contract hashes", Short: "Dump deployed contract hashes",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: dumpContractHashes, RunE: dumpContractHashes,
} }
@ -174,7 +172,7 @@ var (
Use: "dump-config", Use: "dump-config",
Short: "Dump FrostFS network config", Short: "Dump FrostFS network config",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: dumpNetworkConfig, RunE: dumpNetworkConfig,
} }
@ -183,7 +181,7 @@ var (
Use: "dump-balances", Use: "dump-balances",
Short: "Dump GAS balances", Short: "Dump GAS balances",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: dumpBalances, RunE: dumpBalances,
} }
@ -193,7 +191,7 @@ var (
Short: "Update FrostFS contracts", Short: "Update FrostFS contracts",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: updateContracts, RunE: updateContracts,
} }
@ -202,7 +200,7 @@ var (
Use: "dump-containers", Use: "dump-containers",
Short: "Dump FrostFS containers to file", Short: "Dump FrostFS containers to file",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: dumpContainers, RunE: dumpContainers,
} }
@ -212,7 +210,7 @@ var (
Short: "Restore FrostFS containers from file", Short: "Restore FrostFS containers from file",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: restoreContainers, RunE: restoreContainers,
} }
@ -221,7 +219,7 @@ var (
Use: "list-containers", Use: "list-containers",
Short: "List FrostFS containers", Short: "List FrostFS containers",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: listContainers, RunE: listContainers,
} }
@ -230,7 +228,7 @@ var (
Use: "deposit-notary", Use: "deposit-notary",
Short: "Deposit GAS for notary service", Short: "Deposit GAS for notary service",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
RunE: depositNotary, RunE: depositNotary,
} }
@ -239,7 +237,7 @@ var (
Use: "netmap-candidates", Use: "netmap-candidates",
Short: "List netmap candidates nodes", Short: "List netmap candidates nodes",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
}, },
Run: listNetmapCandidatesNodes, Run: listNetmapCandidatesNodes,
@ -250,7 +248,7 @@ var (
Short: "Adds account to proxy contract", Short: "Adds account to proxy contract",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
Run: addProxyAccount, Run: addProxyAccount,
} }
@ -260,7 +258,7 @@ var (
Short: "Remove from proxy contract", Short: "Remove from proxy contract",
PreRun: func(cmd *cobra.Command, _ []string) { PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag)) _ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag)) _ = viper.BindPFlag(util.EndpointFlag, cmd.Flags().Lookup(util.EndpointFlag))
}, },
Run: removeProxyAccount, Run: removeProxyAccount,
} }
@ -313,24 +311,24 @@ func init() {
func initProxyAddAccount() { func initProxyAddAccount() {
RootCmd.AddCommand(proxyAddAccountCmd) RootCmd.AddCommand(proxyAddAccountCmd)
proxyAddAccountCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) proxyAddAccountCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
proxyAddAccountCmd.Flags().String(accountAddressFlag, "", "Wallet address string") proxyAddAccountCmd.Flags().String(accountAddressFlag, "", "Wallet address string")
} }
func initProxyRemoveAccount() { func initProxyRemoveAccount() {
RootCmd.AddCommand(proxyRemoveAccountCmd) RootCmd.AddCommand(proxyRemoveAccountCmd)
proxyRemoveAccountCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) proxyRemoveAccountCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
proxyRemoveAccountCmd.Flags().String(accountAddressFlag, "", "Wallet address string") proxyRemoveAccountCmd.Flags().String(accountAddressFlag, "", "Wallet address string")
} }
func initNetmapCandidatesCmd() { func initNetmapCandidatesCmd() {
RootCmd.AddCommand(netmapCandidatesCmd) RootCmd.AddCommand(netmapCandidatesCmd)
netmapCandidatesCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) netmapCandidatesCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
} }
func initDepositoryNotaryCmd() { func initDepositoryNotaryCmd() {
RootCmd.AddCommand(depositNotaryCmd) RootCmd.AddCommand(depositNotaryCmd)
depositNotaryCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) depositNotaryCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
depositNotaryCmd.Flags().String(storageWalletFlag, "", "Path to storage node wallet") depositNotaryCmd.Flags().String(storageWalletFlag, "", "Path to storage node wallet")
depositNotaryCmd.Flags().String(walletAccountFlag, "", "Wallet account address") depositNotaryCmd.Flags().String(walletAccountFlag, "", "Wallet account address")
depositNotaryCmd.Flags().String(refillGasAmountFlag, "", "Amount of GAS to deposit") depositNotaryCmd.Flags().String(refillGasAmountFlag, "", "Amount of GAS to deposit")
@ -340,7 +338,7 @@ func initDepositoryNotaryCmd() {
func initRefillGasCmd() { func initRefillGasCmd() {
RootCmd.AddCommand(refillGasCmd) RootCmd.AddCommand(refillGasCmd)
refillGasCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) refillGasCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
refillGasCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) refillGasCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
refillGasCmd.Flags().String(storageWalletFlag, "", "Path to storage node wallet") refillGasCmd.Flags().String(storageWalletFlag, "", "Path to storage node wallet")
refillGasCmd.Flags().String(walletAddressFlag, "", "Address of wallet") refillGasCmd.Flags().String(walletAddressFlag, "", "Address of wallet")
refillGasCmd.Flags().String(refillGasAmountFlag, "", "Additional amount of GAS to transfer") refillGasCmd.Flags().String(refillGasAmountFlag, "", "Additional amount of GAS to transfer")
@ -349,21 +347,21 @@ func initRefillGasCmd() {
func initListContainersCmd() { func initListContainersCmd() {
RootCmd.AddCommand(listContainersCmd) RootCmd.AddCommand(listContainersCmd)
listContainersCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) listContainersCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
listContainersCmd.Flags().String(containerContractFlag, "", "Container contract hash (for networks without NNS)") listContainersCmd.Flags().String(containerContractFlag, "", "Container contract hash (for networks without NNS)")
} }
func initRestoreContainersCmd() { func initRestoreContainersCmd() {
RootCmd.AddCommand(restoreContainersCmd) RootCmd.AddCommand(restoreContainersCmd)
restoreContainersCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) restoreContainersCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
restoreContainersCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) restoreContainersCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
restoreContainersCmd.Flags().String(containerDumpFlag, "", "File to restore containers from") restoreContainersCmd.Flags().String(containerDumpFlag, "", "File to restore containers from")
restoreContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "Containers to restore") restoreContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "Containers to restore")
} }
func initDumpContainersCmd() { func initDumpContainersCmd() {
RootCmd.AddCommand(dumpContainersCmd) RootCmd.AddCommand(dumpContainersCmd)
dumpContainersCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) dumpContainersCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
dumpContainersCmd.Flags().String(containerDumpFlag, "", "File where to save dumped containers") dumpContainersCmd.Flags().String(containerDumpFlag, "", "File where to save dumped containers")
dumpContainersCmd.Flags().String(containerContractFlag, "", "Container contract hash (for networks without NNS)") dumpContainersCmd.Flags().String(containerContractFlag, "", "Container contract hash (for networks without NNS)")
dumpContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "Containers to dump") dumpContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "Containers to dump")
@ -372,7 +370,7 @@ func initDumpContainersCmd() {
func initUpdateContractsCmd() { func initUpdateContractsCmd() {
RootCmd.AddCommand(updateContractsCmd) RootCmd.AddCommand(updateContractsCmd)
updateContractsCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) updateContractsCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
updateContractsCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) updateContractsCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
updateContractsCmd.Flags().String(contractsInitFlag, "", contractsInitFlagDesc) updateContractsCmd.Flags().String(contractsInitFlag, "", contractsInitFlagDesc)
updateContractsCmd.Flags().String(contractsURLFlag, "", contractsURLFlagDesc) updateContractsCmd.Flags().String(contractsURLFlag, "", contractsURLFlagDesc)
updateContractsCmd.MarkFlagsMutuallyExclusive(contractsInitFlag, contractsURLFlag) updateContractsCmd.MarkFlagsMutuallyExclusive(contractsInitFlag, contractsURLFlag)
@ -380,7 +378,7 @@ func initUpdateContractsCmd() {
func initDumpBalancesCmd() { func initDumpBalancesCmd() {
RootCmd.AddCommand(dumpBalancesCmd) RootCmd.AddCommand(dumpBalancesCmd)
dumpBalancesCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) dumpBalancesCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
dumpBalancesCmd.Flags().BoolP(dumpBalancesStorageFlag, "s", false, "Dump balances of storage nodes from the current netmap") dumpBalancesCmd.Flags().BoolP(dumpBalancesStorageFlag, "s", false, "Dump balances of storage nodes from the current netmap")
dumpBalancesCmd.Flags().BoolP(dumpBalancesAlphabetFlag, "a", false, "Dump balances of alphabet contracts") dumpBalancesCmd.Flags().BoolP(dumpBalancesAlphabetFlag, "a", false, "Dump balances of alphabet contracts")
dumpBalancesCmd.Flags().BoolP(dumpBalancesProxyFlag, "p", false, "Dump balances of the proxy contract") dumpBalancesCmd.Flags().BoolP(dumpBalancesProxyFlag, "p", false, "Dump balances of the proxy contract")
@ -390,52 +388,52 @@ func initDumpBalancesCmd() {
func initSetConfigCmd() { func initSetConfigCmd() {
RootCmd.AddCommand(setConfig) RootCmd.AddCommand(setConfig)
setConfig.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) setConfig.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
setConfig.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) setConfig.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
setConfig.Flags().Bool(forceConfigSet, false, "Force setting not well-known configuration key") setConfig.Flags().Bool(forceConfigSet, false, "Force setting not well-known configuration key")
setConfig.Flags().String(localDumpFlag, "", "Path to the blocks dump file") setConfig.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
} }
func initDumpNetworkConfigCmd() { func initDumpNetworkConfigCmd() {
RootCmd.AddCommand(dumpNetworkConfigCmd) RootCmd.AddCommand(dumpNetworkConfigCmd)
dumpNetworkConfigCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) dumpNetworkConfigCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
} }
func initDumpContractHashesCmd() { func initDumpContractHashesCmd() {
RootCmd.AddCommand(dumpContractHashesCmd) RootCmd.AddCommand(dumpContractHashesCmd)
dumpContractHashesCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) dumpContractHashesCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
dumpContractHashesCmd.Flags().String(customZoneFlag, "", "Custom zone to search.") dumpContractHashesCmd.Flags().String(customZoneFlag, "", "Custom zone to search.")
} }
func initSetPolicyCmd() { func initSetPolicyCmd() {
RootCmd.AddCommand(setPolicy) RootCmd.AddCommand(setPolicy)
setPolicy.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) setPolicy.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
setPolicy.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) setPolicy.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
setPolicy.Flags().String(localDumpFlag, "", "Path to the blocks dump file") setPolicy.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
} }
func initDumpPolicyCmd() { func initDumpPolicyCmd() {
RootCmd.AddCommand(dumpPolicy) RootCmd.AddCommand(dumpPolicy)
dumpPolicy.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) dumpPolicy.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
} }
func initRemoveNodesCmd() { func initRemoveNodesCmd() {
RootCmd.AddCommand(removeNodes) RootCmd.AddCommand(removeNodes)
removeNodes.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) removeNodes.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
removeNodes.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) removeNodes.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
removeNodes.Flags().String(localDumpFlag, "", "Path to the blocks dump file") removeNodes.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
} }
func initForceNewEpochCmd() { func initForceNewEpochCmd() {
RootCmd.AddCommand(forceNewEpoch) RootCmd.AddCommand(forceNewEpoch)
forceNewEpoch.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) forceNewEpoch.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
forceNewEpoch.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) forceNewEpoch.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
forceNewEpoch.Flags().String(localDumpFlag, "", "Path to the blocks dump file") forceNewEpoch.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
} }
func initGenerateStorageCmd() { func initGenerateStorageCmd() {
RootCmd.AddCommand(generateStorageCmd) RootCmd.AddCommand(generateStorageCmd)
generateStorageCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) generateStorageCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
generateStorageCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) generateStorageCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
generateStorageCmd.Flags().String(storageWalletFlag, "", "Path to new storage node wallet") generateStorageCmd.Flags().String(storageWalletFlag, "", "Path to new storage node wallet")
generateStorageCmd.Flags().String(storageGasCLIFlag, "", "Initial amount of GAS to transfer") generateStorageCmd.Flags().String(storageGasCLIFlag, "", "Initial amount of GAS to transfer")
generateStorageCmd.Flags().StringP(storageWalletLabelFlag, "l", "", "Wallet label") generateStorageCmd.Flags().StringP(storageWalletLabelFlag, "l", "", "Wallet label")
@ -444,7 +442,7 @@ func initGenerateStorageCmd() {
func initInitCmd() { func initInitCmd() {
RootCmd.AddCommand(initCmd) RootCmd.AddCommand(initCmd)
initCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc) initCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
initCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc) initCmd.Flags().StringP(util.EndpointFlag, util.EndpointFlagShort, "", util.EndpointFlagDesc)
initCmd.Flags().String(contractsInitFlag, "", contractsInitFlagDesc) initCmd.Flags().String(contractsInitFlag, "", contractsInitFlagDesc)
initCmd.Flags().String(contractsURLFlag, "", contractsURLFlagDesc) initCmd.Flags().String(contractsURLFlag, "", contractsURLFlagDesc)
initCmd.Flags().Uint(epochDurationCLIFlag, 240, "Amount of side chain blocks in one FrostFS epoch") initCmd.Flags().Uint(epochDurationCLIFlag, 240, "Amount of side chain blocks in one FrostFS epoch")
@ -453,7 +451,7 @@ func initInitCmd() {
// Defaults are taken from neo-preodolenie. // Defaults are taken from neo-preodolenie.
initCmd.Flags().Uint64(containerFeeCLIFlag, 1000, "Container registration fee") initCmd.Flags().Uint64(containerFeeCLIFlag, 1000, "Container registration fee")
initCmd.Flags().Uint64(containerAliasFeeCLIFlag, 500, "Container alias fee") initCmd.Flags().Uint64(containerAliasFeeCLIFlag, 500, "Container alias fee")
initCmd.Flags().String(protoConfigPath, "", "Path to the consensus node configuration") initCmd.Flags().String(util.ProtoConfigPath, "", "Path to the consensus node configuration")
initCmd.Flags().String(localDumpFlag, "", "Path to the blocks dump file") initCmd.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
initCmd.MarkFlagsMutuallyExclusive(contractsInitFlag, contractsURLFlag) initCmd.MarkFlagsMutuallyExclusive(contractsInitFlag, contractsURLFlag)
} }

View file

@ -0,0 +1,15 @@
package util
const (
ConsensusAccountName = "consensus"
ProtoConfigPath = "protocol"
// MaxAlphabetNodes is the maximum number of candidates allowed, which is currently limited by the size
// of the invocation script.
// See: https://github.com/nspcc-dev/neo-go/blob/740488f7f35e367eaa99a71c0a609c315fe2b0fc/pkg/core/transaction/witness.go#L10
MaxAlphabetNodes = 22
EndpointFlag = "rpc-endpoint"
EndpointFlagDesc = "N3 RPC node endpoint"
EndpointFlagShort = "r"
)

View file

@ -0,0 +1,90 @@
package util
import (
"fmt"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
"github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var ErrTooManyAlphabetNodes = fmt.Errorf("too many alphabet nodes (maximum allowed is %d)", MaxAlphabetNodes)
func AwaitTx(cmd *cobra.Command, c Client, txs []HashVUBPair) error {
cmd.Println("Waiting for transactions to persist...")
at := trigger.Application
var retErr error
loop:
for i := range txs {
var it int
var pollInterval time.Duration
var pollIntervalChanged bool
for {
// We must fetch current height before application log, to avoid race condition.
currBlock, err := c.GetBlockCount()
if err != nil {
return fmt.Errorf("can't fetch current block height: %w", err)
}
res, err := c.GetApplicationLog(txs[i].Hash, &at)
if err == nil {
if retErr == nil && len(res.Executions) > 0 && res.Executions[0].VMState != vmstate.Halt {
retErr = fmt.Errorf("tx %d persisted in %s state: %s",
i, res.Executions[0].VMState, res.Executions[0].FaultException)
}
continue loop
}
if txs[i].Vub < currBlock {
return fmt.Errorf("tx was not persisted: Vub=%d, height=%d", txs[i].Vub, currBlock)
}
pollInterval, pollIntervalChanged = NextPollInterval(it, pollInterval)
if pollIntervalChanged && viper.GetBool(commonflags.Verbose) {
cmd.Printf("Pool interval to check transaction persistence changed: %s\n", pollInterval.String())
}
timer := time.NewTimer(pollInterval)
select {
case <-cmd.Context().Done():
return cmd.Context().Err()
case <-timer.C:
}
it++
}
}
return retErr
}
func NextPollInterval(it int, previous time.Duration) (time.Duration, bool) {
const minPollInterval = 1 * time.Second
const maxPollInterval = 16 * time.Second
const changeAfter = 5
if it == 0 {
return minPollInterval, true
}
if it%changeAfter != 0 {
return previous, false
}
nextInterval := previous * 2
if nextInterval > maxPollInterval {
return maxPollInterval, previous != maxPollInterval
}
return nextInterval, true
}
func GetWalletAccount(w *wallet.Wallet, typ string) (*wallet.Account, error) {
for i := range w.Accounts {
if w.Accounts[i].Label == typ {
return w.Accounts[i], nil
}
}
return nil, fmt.Errorf("account for '%s' not found", typ)
}

View file

@ -1,4 +1,4 @@
package morph package util
import ( import (
"crypto/elliptic" "crypto/elliptic"
@ -38,7 +38,7 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
type localClient struct { type LocalClient struct {
bc *core.Blockchain bc *core.Blockchain
transactions []*transaction.Transaction transactions []*transaction.Transaction
dumpPath string dumpPath string
@ -46,8 +46,8 @@ type localClient struct {
maxGasInvoke int64 maxGasInvoke int64
} }
func newLocalClient(cmd *cobra.Command, v *viper.Viper, wallets []*wallet.Wallet, dumpPath string) (*localClient, error) { func NewLocalClient(cmd *cobra.Command, v *viper.Viper, wallets []*wallet.Wallet, dumpPath string) (*LocalClient, error) {
cfg, err := config.LoadFile(v.GetString(protoConfigPath)) cfg, err := config.LoadFile(v.GetString(ProtoConfigPath))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -60,7 +60,7 @@ func newLocalClient(cmd *cobra.Command, v *viper.Viper, wallets []*wallet.Wallet
m := smartcontract.GetDefaultHonestNodeCount(int(cfg.ProtocolConfiguration.ValidatorsCount)) m := smartcontract.GetDefaultHonestNodeCount(int(cfg.ProtocolConfiguration.ValidatorsCount))
accounts := make([]*wallet.Account, len(wallets)) accounts := make([]*wallet.Account, len(wallets))
for i := range accounts { for i := range accounts {
accounts[i], err = getWalletAccount(wallets[i], consensusAccountName) accounts[i], err = GetWalletAccount(wallets[i], ConsensusAccountName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -102,7 +102,7 @@ func newLocalClient(cmd *cobra.Command, v *viper.Viper, wallets []*wallet.Wallet
} }
} }
return &localClient{ return &LocalClient{
bc: bc, bc: bc,
dumpPath: dumpPath, dumpPath: dumpPath,
accounts: accounts[:m], accounts: accounts[:m],
@ -110,15 +110,15 @@ func newLocalClient(cmd *cobra.Command, v *viper.Viper, wallets []*wallet.Wallet
}, nil }, nil
} }
func (l *localClient) GetBlockCount() (uint32, error) { func (l *LocalClient) GetBlockCount() (uint32, error) {
return l.bc.BlockHeight(), nil return l.bc.BlockHeight(), nil
} }
func (l *localClient) GetNativeContracts() ([]state.NativeContract, error) { func (l *LocalClient) GetNativeContracts() ([]state.NativeContract, error) {
return l.bc.GetNatives(), nil return l.bc.GetNatives(), nil
} }
func (l *localClient) GetApplicationLog(h util.Uint256, t *trigger.Type) (*result.ApplicationLog, error) { func (l *LocalClient) GetApplicationLog(h util.Uint256, t *trigger.Type) (*result.ApplicationLog, error) {
aer, err := l.bc.GetAppExecResults(h, *t) aer, err := l.bc.GetAppExecResults(h, *t)
if err != nil { if err != nil {
return nil, err return nil, err
@ -128,13 +128,13 @@ func (l *localClient) GetApplicationLog(h util.Uint256, t *trigger.Type) (*resul
return &a, nil return &a, nil
} }
func (l *localClient) GetCommittee() (keys.PublicKeys, error) { func (l *LocalClient) GetCommittee() (keys.PublicKeys, error) {
// not used by `morph init` command // not used by `morph init` command
panic("unexpected call") panic("unexpected call")
} }
// InvokeFunction is implemented via `InvokeScript`. // InvokeFunction is implemented via `InvokeScript`.
func (l *localClient) InvokeFunction(h util.Uint160, method string, sPrm []smartcontract.Parameter, ss []transaction.Signer) (*result.Invoke, error) { func (l *LocalClient) InvokeFunction(h util.Uint160, method string, sPrm []smartcontract.Parameter, ss []transaction.Signer) (*result.Invoke, error) {
var err error var err error
pp := make([]any, len(sPrm)) pp := make([]any, len(sPrm))
@ -145,21 +145,21 @@ func (l *localClient) InvokeFunction(h util.Uint160, method string, sPrm []smart
} }
} }
return invokeFunction(l, h, method, pp, ss) return InvokeFunction(l, h, method, pp, ss)
} }
func (l *localClient) TerminateSession(_ uuid.UUID) (bool, error) { func (l *LocalClient) TerminateSession(_ uuid.UUID) (bool, error) {
// not used by `morph init` command // not used by `morph init` command
panic("unexpected call") panic("unexpected call")
} }
func (l *localClient) TraverseIterator(_, _ uuid.UUID, _ int) ([]stackitem.Item, error) { func (l *LocalClient) TraverseIterator(_, _ uuid.UUID, _ int) ([]stackitem.Item, error) {
// not used by `morph init` command // not used by `morph init` command
panic("unexpected call") panic("unexpected call")
} }
// GetVersion return default version. // GetVersion return default version.
func (l *localClient) GetVersion() (*result.Version, error) { func (l *LocalClient) GetVersion() (*result.Version, error) {
c := l.bc.GetConfig() c := l.bc.GetConfig()
return &result.Version{ return &result.Version{
Protocol: result.Protocol{ Protocol: result.Protocol{
@ -180,7 +180,7 @@ func (l *localClient) GetVersion() (*result.Version, error) {
}, nil }, nil
} }
func (l *localClient) InvokeContractVerify(util.Uint160, []smartcontract.Parameter, []transaction.Signer, ...transaction.Witness) (*result.Invoke, error) { func (l *LocalClient) InvokeContractVerify(util.Uint160, []smartcontract.Parameter, []transaction.Signer, ...transaction.Witness) (*result.Invoke, error) {
// not used by `morph init` command // not used by `morph init` command
panic("unexpected call") panic("unexpected call")
} }
@ -188,7 +188,7 @@ func (l *localClient) InvokeContractVerify(util.Uint160, []smartcontract.Paramet
// CalculateNetworkFee calculates network fee for the given transaction. // CalculateNetworkFee calculates network fee for the given transaction.
// Copied from neo-go with minor corrections (no need to support non-notary mode): // Copied from neo-go with minor corrections (no need to support non-notary mode):
// https://github.com/nspcc-dev/neo-go/blob/v0.103.0/pkg/services/rpcsrv/server.go#L911 // https://github.com/nspcc-dev/neo-go/blob/v0.103.0/pkg/services/rpcsrv/server.go#L911
func (l *localClient) CalculateNetworkFee(tx *transaction.Transaction) (int64, error) { func (l *LocalClient) CalculateNetworkFee(tx *transaction.Transaction) (int64, error) {
// Avoid setting hash for this tx: server code doesn't touch client transaction. // Avoid setting hash for this tx: server code doesn't touch client transaction.
data := tx.Bytes() data := tx.Bytes()
tx, err := transaction.NewTransactionFromBytes(data) tx, err := transaction.NewTransactionFromBytes(data)
@ -259,7 +259,7 @@ func (l *localClient) CalculateNetworkFee(tx *transaction.Transaction) (int64, e
return netFee, nil return netFee, nil
} }
func (l *localClient) InvokeScript(script []byte, signers []transaction.Signer) (*result.Invoke, error) { func (l *LocalClient) InvokeScript(script []byte, signers []transaction.Signer) (*result.Invoke, error) {
lastBlock, err := l.bc.GetBlock(l.bc.CurrentBlockHash()) lastBlock, err := l.bc.GetBlock(l.bc.CurrentBlockHash())
if err != nil { if err != nil {
return nil, err return nil, err
@ -295,7 +295,7 @@ func (l *localClient) InvokeScript(script []byte, signers []transaction.Signer)
}, nil }, nil
} }
func (l *localClient) SendRawTransaction(tx *transaction.Transaction) (util.Uint256, error) { func (l *LocalClient) SendRawTransaction(tx *transaction.Transaction) (util.Uint256, error) {
// We need to test that transaction was formed correctly to catch as many errors as we can. // We need to test that transaction was formed correctly to catch as many errors as we can.
bs := tx.Bytes() bs := tx.Bytes()
_, err := transaction.NewTransactionFromBytes(bs) _, err := transaction.NewTransactionFromBytes(bs)
@ -307,7 +307,7 @@ func (l *localClient) SendRawTransaction(tx *transaction.Transaction) (util.Uint
return tx.Hash(), nil return tx.Hash(), nil
} }
func (l *localClient) putTransactions() error { func (l *LocalClient) putTransactions() error {
// 1. Prepare new block. // 1. Prepare new block.
lastBlock, err := l.bc.GetBlock(l.bc.CurrentBlockHash()) lastBlock, err := l.bc.GetBlock(l.bc.CurrentBlockHash())
if err != nil { if err != nil {
@ -349,7 +349,7 @@ func (l *localClient) putTransactions() error {
return l.bc.AddBlock(b) return l.bc.AddBlock(b)
} }
func invokeFunction(c Client, h util.Uint160, method string, parameters []any, signers []transaction.Signer) (*result.Invoke, error) { func InvokeFunction(c Client, h util.Uint160, method string, parameters []any, signers []transaction.Signer) (*result.Invoke, error) {
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
emit.Array(w.BinWriter, parameters...) emit.Array(w.BinWriter, parameters...)
emit.AppCallNoArgs(w.BinWriter, h, method, callflag.All) emit.AppCallNoArgs(w.BinWriter, h, method, callflag.All)
@ -361,7 +361,7 @@ func invokeFunction(c Client, h util.Uint160, method string, parameters []any, s
var errGetDesignatedByRoleResponse = errors.New("`getDesignatedByRole`: invalid response") var errGetDesignatedByRoleResponse = errors.New("`getDesignatedByRole`: invalid response")
func getDesignatedByRole(inv *invoker.Invoker, h util.Uint160, role noderoles.Role, u uint32) (keys.PublicKeys, error) { func GetDesignatedByRole(inv *invoker.Invoker, h util.Uint160, role noderoles.Role, u uint32) (keys.PublicKeys, error) {
arr, err := unwrap.Array(inv.Call(h, "getDesignatedByRole", int64(role), int64(u))) arr, err := unwrap.Array(inv.Call(h, "getDesignatedByRole", int64(role), int64(u)))
if err != nil { if err != nil {
return nil, errGetDesignatedByRoleResponse return nil, errGetDesignatedByRoleResponse
@ -382,7 +382,7 @@ func getDesignatedByRole(inv *invoker.Invoker, h util.Uint160, role noderoles.Ro
return pubs, nil return pubs, nil
} }
func (l *localClient) dump() (err error) { func (l *LocalClient) Dump() (err error) {
defer l.bc.Close() defer l.bc.Close()
f, err := os.Create(l.dumpPath) f, err := os.Create(l.dumpPath)

View file

@ -1,4 +1,4 @@
package morph package util
import ( import (
"context" "context"
@ -34,19 +34,19 @@ type Client interface {
CalculateNetworkFee(tx *transaction.Transaction) (int64, error) CalculateNetworkFee(tx *transaction.Transaction) (int64, error)
} }
type hashVUBPair struct { type HashVUBPair struct {
hash util.Uint256 Hash util.Uint256
vub uint32 Vub uint32
} }
type clientContext struct { type ClientContext struct {
Client Client // a raw neo-go client OR a local chain implementation Client Client // a raw neo-go client OR a local chain implementation
CommitteeAct *actor.Actor // committee actor with the Global witness scope CommitteeAct *actor.Actor // committee actor with the Global witness scope
ReadOnlyInvoker *invoker.Invoker // R/O contract invoker, does not contain any signer ReadOnlyInvoker *invoker.Invoker // R/O contract invoker, does not contain any signer
SentTxs []hashVUBPair SentTxs []HashVUBPair
} }
func getN3Client(v *viper.Viper) (Client, error) { func GetN3Client(v *viper.Viper) (Client, error) {
// number of opened connections // number of opened connections
// by neo-go client per one host // by neo-go client per one host
const ( const (
@ -55,7 +55,7 @@ func getN3Client(v *viper.Viper) (Client, error) {
) )
ctx := context.Background() ctx := context.Background()
endpoint := v.GetString(endpointFlag) endpoint := v.GetString(EndpointFlag)
if endpoint == "" { if endpoint == "" {
return nil, errors.New("missing endpoint") return nil, errors.New("missing endpoint")
} }
@ -72,20 +72,20 @@ func getN3Client(v *viper.Viper) (Client, error) {
return c, nil return c, nil
} }
func defaultClientContext(c Client, committeeAcc *wallet.Account) (*clientContext, error) { func DefaultClientContext(c Client, committeeAcc *wallet.Account) (*ClientContext, error) {
commAct, err := newActor(c, committeeAcc) commAct, err := NewActor(c, committeeAcc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &clientContext{ return &ClientContext{
Client: c, Client: c,
CommitteeAct: commAct, CommitteeAct: commAct,
ReadOnlyInvoker: invoker.New(c, nil), ReadOnlyInvoker: invoker.New(c, nil),
}, nil }, nil
} }
func (c *clientContext) sendTx(tx *transaction.Transaction, cmd *cobra.Command, await bool) error { func (c *ClientContext) SendTx(tx *transaction.Transaction, cmd *cobra.Command, await bool) error {
h, err := c.Client.SendRawTransaction(tx) h, err := c.Client.SendRawTransaction(tx)
if err != nil { if err != nil {
return err return err
@ -95,10 +95,27 @@ func (c *clientContext) sendTx(tx *transaction.Transaction, cmd *cobra.Command,
return fmt.Errorf("sent and actual tx hashes mismatch:\n\tsent: %v\n\tactual: %v", tx.Hash().StringLE(), h.StringLE()) return fmt.Errorf("sent and actual tx hashes mismatch:\n\tsent: %v\n\tactual: %v", tx.Hash().StringLE(), h.StringLE())
} }
c.SentTxs = append(c.SentTxs, hashVUBPair{hash: h, vub: tx.ValidUntilBlock}) c.SentTxs = append(c.SentTxs, HashVUBPair{Hash: h, Vub: tx.ValidUntilBlock})
if await { if await {
return c.awaitTx(cmd) return c.AwaitTx(cmd)
} }
return nil return nil
} }
func (c *ClientContext) AwaitTx(cmd *cobra.Command) error {
if len(c.SentTxs) == 0 {
return nil
}
if local, ok := c.Client.(*LocalClient); ok {
if err := local.putTransactions(); err != nil {
return fmt.Errorf("can't persist transactions: %w", err)
}
}
err := AwaitTx(cmd, c.Client, c.SentTxs)
c.SentTxs = c.SentTxs[:0]
return err
}

View file

@ -1,4 +1,4 @@
package morph package util
import ( import (
"errors" "errors"
@ -15,19 +15,19 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
) )
func getAlphabetWallets(v *viper.Viper, walletDir string) ([]*wallet.Wallet, error) { func GetAlphabetWallets(v *viper.Viper, walletDir string) ([]*wallet.Wallet, error) {
wallets, err := openAlphabetWallets(v, walletDir) wallets, err := OpenAlphabetWallets(v, walletDir)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(wallets) > maxAlphabetNodes { if len(wallets) > MaxAlphabetNodes {
return nil, ErrTooManyAlphabetNodes return nil, ErrTooManyAlphabetNodes
} }
return wallets, nil return wallets, nil
} }
func openAlphabetWallets(v *viper.Viper, walletDir string) ([]*wallet.Wallet, error) { func OpenAlphabetWallets(v *viper.Viper, walletDir string) ([]*wallet.Wallet, error) {
walletFiles, err := os.ReadDir(walletDir) walletFiles, err := os.ReadDir(walletDir)
if err != nil { if err != nil {
return nil, fmt.Errorf("can't read alphabet wallets dir: %w", err) return nil, fmt.Errorf("can't read alphabet wallets dir: %w", err)
@ -75,7 +75,7 @@ loop:
return wallets, nil return wallets, nil
} }
func newActor(c actor.RPCActor, committeeAcc *wallet.Account) (*actor.Actor, error) { func NewActor(c actor.RPCActor, committeeAcc *wallet.Account) (*actor.Actor, error) {
return actor.New(c, []actor.SignerAccount{{ return actor.New(c, []actor.SignerAccount{{
Signer: transaction.Signer{ Signer: transaction.Signer{
Account: committeeAcc.Contract.ScriptHash(), Account: committeeAcc.Contract.ScriptHash(),