adm: Add commands to invoke methods of policy
contract #868
5 changed files with 120 additions and 91 deletions
cmd/frostfs-adm/internal/modules/morph
|
@ -46,10 +46,10 @@ NNS name is taken by stripping '_contract.nef' from the NEF file (similar to fro
|
|||
func init() {
|
||||
ff := deployCmd.Flags()
|
||||
|
||||
ff.String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
ff.String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
_ = deployCmd.MarkFlagFilename(alphabetWalletsFlag)
|
||||
|
||||
ff.StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
ff.StringP(endpointFlag, "r", "", endpointFlagDesc)
|
||||
ff.String(contractPathFlag, "", "Path to the contract directory")
|
||||
_ = deployCmd.MarkFlagFilename(contractPathFlag)
|
||||
|
||||
|
|
|
@ -4,12 +4,10 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"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/pkg/innerring"
|
||||
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/state"
|
||||
|
@ -117,15 +115,11 @@ func (c *initializeContext) close() {
|
|||
|
||||
func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContext, error) {
|
||||
walletDir := config.ResolveHomePath(viper.GetString(alphabetWalletsFlag))
|
||||
wallets, err := openAlphabetWallets(v, walletDir)
|
||||
wallets, err := getAlphabetWallets(v, walletDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(wallets) > maxAlphabetNodes {
|
||||
return nil, ErrTooManyAlphabetNodes
|
||||
}
|
||||
|
||||
needContracts := cmd.Name() == "update-contracts" || cmd.Name() == "init"
|
||||
|
||||
var w *wallet.Wallet
|
||||
|
@ -257,54 +251,6 @@ func createWalletAccounts(wallets []*wallet.Wallet) ([]*wallet.Account, error) {
|
|||
return accounts, nil
|
||||
}
|
||||
|
||||
func openAlphabetWallets(v *viper.Viper, walletDir string) ([]*wallet.Wallet, error) {
|
||||
walletFiles, err := os.ReadDir(walletDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't read alphabet wallets dir: %w", err)
|
||||
}
|
||||
|
||||
var size int
|
||||
loop:
|
||||
for i := 0; i < len(walletFiles); i++ {
|
||||
name := innerring.GlagoliticLetter(i).String() + ".json"
|
||||
for j := range walletFiles {
|
||||
if walletFiles[j].Name() == name {
|
||||
size++
|
||||
continue loop
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
if size == 0 {
|
||||
return nil, errors.New("alphabet wallets dir is empty (run `generate-alphabet` command first)")
|
||||
}
|
||||
|
||||
wallets := make([]*wallet.Wallet, size)
|
||||
for i := 0; i < size; i++ {
|
||||
letter := innerring.GlagoliticLetter(i).String()
|
||||
p := filepath.Join(walletDir, letter+".json")
|
||||
w, err := wallet.NewWalletFromFile(p)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't open wallet: %w", err)
|
||||
}
|
||||
|
||||
password, err := config.GetPassword(v, letter)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't fetch password: %w", err)
|
||||
}
|
||||
|
||||
for i := range w.Accounts {
|
||||
if err := w.Accounts[i].Decrypt(password, keys.NEP2ScryptParams()); err != nil {
|
||||
return nil, fmt.Errorf("can't unlock wallet: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
wallets[i] = w
|
||||
}
|
||||
|
||||
return wallets, nil
|
||||
}
|
||||
|
||||
func (c *initializeContext) awaitTx() error {
|
||||
return c.clientContext.awaitTx(c.Command)
|
||||
}
|
||||
|
|
|
@ -73,13 +73,7 @@ func getN3Client(v *viper.Viper) (Client, error) {
|
|||
}
|
||||
|
||||
func defaultClientContext(c Client, committeeAcc *wallet.Account) (*clientContext, error) {
|
||||
commAct, err := actor.New(c, []actor.SignerAccount{{
|
||||
Signer: transaction.Signer{
|
||||
Account: committeeAcc.Contract.ScriptHash(),
|
||||
Scopes: transaction.Global,
|
||||
},
|
||||
Account: committeeAcc,
|
||||
}})
|
||||
commAct, err := newActor(c, committeeAcc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -7,8 +7,11 @@ import (
|
|||
|
||||
const (
|
||||
alphabetWalletsFlag = "alphabet-wallets"
|
||||
alphabetWalletsFlagDesc = "Path to alphabet wallets dir"
|
||||
alphabetSizeFlag = "size"
|
||||
endpointFlag = "rpc-endpoint"
|
||||
endpointFlagDesc = "N3 RPC node endpoint"
|
||||
endpointFlagShort = "r"
|
||||
storageWalletFlag = "storage-wallet"
|
||||
storageWalletLabelFlag = "label"
|
||||
storageGasCLIFlag = "initial-gas"
|
||||
|
@ -264,12 +267,12 @@ func init() {
|
|||
|
||||
func initNetmapCandidatesCmd() {
|
||||
RootCmd.AddCommand(netmapCandidatesCmd)
|
||||
netmapCandidatesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
netmapCandidatesCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
}
|
||||
|
||||
func initDepositoryNotaryCmd() {
|
||||
RootCmd.AddCommand(depositNotaryCmd)
|
||||
depositNotaryCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
depositNotaryCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
depositNotaryCmd.Flags().String(storageWalletFlag, "", "Path to storage node wallet")
|
||||
depositNotaryCmd.Flags().String(walletAccountFlag, "", "Wallet account address")
|
||||
depositNotaryCmd.Flags().String(refillGasAmountFlag, "", "Amount of GAS to deposit")
|
||||
|
@ -278,8 +281,8 @@ func initDepositoryNotaryCmd() {
|
|||
|
||||
func initRefillGasCmd() {
|
||||
RootCmd.AddCommand(refillGasCmd)
|
||||
refillGasCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
refillGasCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
refillGasCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
refillGasCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
refillGasCmd.Flags().String(storageWalletFlag, "", "Path to storage node wallet")
|
||||
refillGasCmd.Flags().String(walletAddressFlag, "", "Address of wallet")
|
||||
refillGasCmd.Flags().String(refillGasAmountFlag, "", "Additional amount of GAS to transfer")
|
||||
|
@ -288,21 +291,21 @@ func initRefillGasCmd() {
|
|||
|
||||
func initListContainersCmd() {
|
||||
RootCmd.AddCommand(listContainersCmd)
|
||||
listContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
listContainersCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
listContainersCmd.Flags().String(containerContractFlag, "", "Container contract hash (for networks without NNS)")
|
||||
}
|
||||
|
||||
func initRestoreContainersCmd() {
|
||||
RootCmd.AddCommand(restoreContainersCmd)
|
||||
restoreContainersCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
restoreContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
restoreContainersCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
restoreContainersCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
restoreContainersCmd.Flags().String(containerDumpFlag, "", "File to restore containers from")
|
||||
restoreContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "Containers to restore")
|
||||
}
|
||||
|
||||
func initDumpContainersCmd() {
|
||||
RootCmd.AddCommand(dumpContainersCmd)
|
||||
dumpContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
dumpContainersCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
dumpContainersCmd.Flags().String(containerDumpFlag, "", "File where to save dumped containers")
|
||||
dumpContainersCmd.Flags().String(containerContractFlag, "", "Container contract hash (for networks without NNS)")
|
||||
dumpContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "Containers to dump")
|
||||
|
@ -310,15 +313,15 @@ func initDumpContainersCmd() {
|
|||
|
||||
func initUpdateContractsCmd() {
|
||||
RootCmd.AddCommand(updateContractsCmd)
|
||||
updateContractsCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
updateContractsCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
updateContractsCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
updateContractsCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
updateContractsCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled FrostFS contracts")
|
||||
_ = updateContractsCmd.MarkFlagRequired(contractsInitFlag)
|
||||
}
|
||||
|
||||
func initDumpBalancesCmd() {
|
||||
RootCmd.AddCommand(dumpBalancesCmd)
|
||||
dumpBalancesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
dumpBalancesCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
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(dumpBalancesProxyFlag, "p", false, "Dump balances of the proxy contract")
|
||||
|
@ -327,53 +330,53 @@ func initDumpBalancesCmd() {
|
|||
|
||||
func initSetConfigCmd() {
|
||||
RootCmd.AddCommand(setConfig)
|
||||
setConfig.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
setConfig.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
setConfig.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
setConfig.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
setConfig.Flags().Bool(forceConfigSet, false, "Force setting not well-known configuration key")
|
||||
setConfig.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
|
||||
}
|
||||
|
||||
func initDumpNetworkConfigCmd() {
|
||||
RootCmd.AddCommand(dumpNetworkConfigCmd)
|
||||
dumpNetworkConfigCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
dumpNetworkConfigCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
}
|
||||
|
||||
func initDumpContractHashesCmd() {
|
||||
RootCmd.AddCommand(dumpContractHashesCmd)
|
||||
dumpContractHashesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
dumpContractHashesCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
dumpContractHashesCmd.Flags().String(customZoneFlag, "", "Custom zone to search.")
|
||||
}
|
||||
|
||||
func initSetPolicyCmd() {
|
||||
RootCmd.AddCommand(setPolicy)
|
||||
setPolicy.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
setPolicy.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
setPolicy.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
setPolicy.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
setPolicy.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
|
||||
}
|
||||
|
||||
func initDumpPolicyCmd() {
|
||||
RootCmd.AddCommand(dumpPolicy)
|
||||
dumpPolicy.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
dumpPolicy.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
}
|
||||
|
||||
func initRemoveNodesCmd() {
|
||||
RootCmd.AddCommand(removeNodes)
|
||||
removeNodes.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
removeNodes.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
removeNodes.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
removeNodes.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
removeNodes.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
|
||||
}
|
||||
|
||||
func initForceNewEpochCmd() {
|
||||
RootCmd.AddCommand(forceNewEpoch)
|
||||
forceNewEpoch.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
forceNewEpoch.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
forceNewEpoch.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
forceNewEpoch.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
forceNewEpoch.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
|
||||
}
|
||||
|
||||
func initGenerateStorageCmd() {
|
||||
RootCmd.AddCommand(generateStorageCmd)
|
||||
generateStorageCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
generateStorageCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
generateStorageCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
generateStorageCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
generateStorageCmd.Flags().String(storageWalletFlag, "", "Path to new storage node wallet")
|
||||
generateStorageCmd.Flags().String(storageGasCLIFlag, "", "Initial amount of GAS to transfer")
|
||||
generateStorageCmd.Flags().StringP(storageWalletLabelFlag, "l", "", "Wallet label")
|
||||
|
@ -381,8 +384,8 @@ func initGenerateStorageCmd() {
|
|||
|
||||
func initInitCmd() {
|
||||
RootCmd.AddCommand(initCmd)
|
||||
initCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
initCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
initCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
initCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
initCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled FrostFS contracts")
|
||||
_ = initCmd.MarkFlagRequired(contractsInitFlag)
|
||||
initCmd.Flags().Uint(epochDurationCLIFlag, 240, "Amount of side chain blocks in one FrostFS epoch")
|
||||
|
@ -397,7 +400,7 @@ func initInitCmd() {
|
|||
|
||||
func initGenerateAlphabetCmd() {
|
||||
RootCmd.AddCommand(generateAlphabetCmd)
|
||||
generateAlphabetCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||
generateAlphabetCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
generateAlphabetCmd.Flags().Uint(alphabetSizeFlag, 7, "Amount of alphabet wallets to generate")
|
||||
}
|
||||
|
||||
|
|
86
cmd/frostfs-adm/internal/modules/morph/util.go
Normal file
86
cmd/frostfs-adm/internal/modules/morph/util.go
Normal file
|
@ -0,0 +1,86 @@
|
|||
package morph
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"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/rpcclient/actor"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func getAlphabetWallets(v *viper.Viper, walletDir string) ([]*wallet.Wallet, error) {
|
||||
wallets, err := openAlphabetWallets(v, walletDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(wallets) > maxAlphabetNodes {
|
||||
return nil, ErrTooManyAlphabetNodes
|
||||
}
|
||||
return wallets, nil
|
||||
}
|
||||
|
||||
func openAlphabetWallets(v *viper.Viper, walletDir string) ([]*wallet.Wallet, error) {
|
||||
walletFiles, err := os.ReadDir(walletDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't read alphabet wallets dir: %w", err)
|
||||
}
|
||||
|
||||
var size int
|
||||
loop:
|
||||
for i := 0; i < len(walletFiles); i++ {
|
||||
name := innerring.GlagoliticLetter(i).String() + ".json"
|
||||
for j := range walletFiles {
|
||||
if walletFiles[j].Name() == name {
|
||||
size++
|
||||
continue loop
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
if size == 0 {
|
||||
return nil, errors.New("alphabet wallets dir is empty (run `generate-alphabet` command first)")
|
||||
}
|
||||
|
||||
wallets := make([]*wallet.Wallet, size)
|
||||
for i := 0; i < size; i++ {
|
||||
letter := innerring.GlagoliticLetter(i).String()
|
||||
p := filepath.Join(walletDir, letter+".json")
|
||||
w, err := wallet.NewWalletFromFile(p)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't open wallet: %w", err)
|
||||
}
|
||||
|
||||
password, err := config.GetPassword(v, letter)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't fetch password: %w", err)
|
||||
}
|
||||
|
||||
for i := range w.Accounts {
|
||||
if err := w.Accounts[i].Decrypt(password, keys.NEP2ScryptParams()); err != nil {
|
||||
return nil, fmt.Errorf("can't unlock wallet: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
wallets[i] = w
|
||||
}
|
||||
|
||||
return wallets, nil
|
||||
}
|
||||
|
||||
func newActor(c actor.RPCActor, committeeAcc *wallet.Account) (*actor.Actor, error) {
|
||||
return actor.New(c, []actor.SignerAccount{{
|
||||
Signer: transaction.Signer{
|
||||
Account: committeeAcc.Contract.ScriptHash(),
|
||||
Scopes: transaction.Global,
|
||||
},
|
||||
Account: committeeAcc,
|
||||
}})
|
||||
}
|
Loading…
Reference in a new issue