[#100] adm: Take net settings into account during netmap contract update

Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
This commit is contained in:
Anton Nikiforov 2023-04-13 17:42:59 +03:00 committed by fyrchik
parent 4496999e52
commit 0c6aeaaf18
4 changed files with 118 additions and 40 deletions

View file

@ -6,6 +6,8 @@ Changelog for FrostFS Node
### Added ### Added
### Changed ### Changed
### Fixed ### Fixed
- Take network settings into account during netmap contract update (#100)
### Removed ### Removed
### Updated ### Updated
### Updating from v0.36.0 ### Updating from v0.36.0

View file

@ -15,7 +15,6 @@ import (
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap" "github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -48,23 +47,12 @@ func dumpNetworkConfig(cmd *cobra.Command, _ []string) error {
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
tw := tabwriter.NewWriter(buf, 0, 2, 2, ' ', 0) tw := tabwriter.NewWriter(buf, 0, 2, 2, ' ', 0)
for _, param := range arr { m, err := parseConfigFromNetmapContract(arr)
tuple, ok := param.Value().([]stackitem.Item) if err != nil {
if !ok || len(tuple) != 2 { return err
return errors.New("invalid ListConfig response from netmap contract") }
} for k, v := range m {
switch k {
k, err := tuple[0].TryBytes()
if err != nil {
return errors.New("invalid config key from netmap contract")
}
v, err := tuple[1].TryBytes()
if err != nil {
return invalidConfigValueErr(k)
}
switch string(k) {
case netmapAuditFeeKey, netmapBasicIncomeRateKey, case netmapAuditFeeKey, netmapBasicIncomeRateKey,
netmapContainerFeeKey, netmapContainerAliasFeeKey, netmapContainerFeeKey, netmapContainerAliasFeeKey,
netmapEigenTrustIterationsKey, netmapEigenTrustIterationsKey,
@ -77,12 +65,10 @@ func dumpNetworkConfig(cmd *cobra.Command, _ []string) error {
case netmapEigenTrustAlphaKey: case netmapEigenTrustAlphaKey:
_, _ = tw.Write([]byte(fmt.Sprintf("%s:\t%s (str)\n", k, v))) _, _ = tw.Write([]byte(fmt.Sprintf("%s:\t%s (str)\n", k, v)))
case netmapHomomorphicHashDisabledKey, netmapMaintenanceAllowedKey: case netmapHomomorphicHashDisabledKey, netmapMaintenanceAllowedKey:
vBool, err := tuple[1].TryBool() if len(v) == 0 || len(v) > 1 {
if err != nil {
return invalidConfigValueErr(k) return invalidConfigValueErr(k)
} }
_, _ = tw.Write([]byte(fmt.Sprintf("%s:\t%t (bool)\n", k, v[0] == 1)))
_, _ = tw.Write([]byte(fmt.Sprintf("%s:\t%t (bool)\n", k, vBool)))
default: default:
_, _ = tw.Write([]byte(fmt.Sprintf("%s:\t%s (hex)\n", k, hex.EncodeToString(v)))) _, _ = tw.Write([]byte(fmt.Sprintf("%s:\t%s (hex)\n", k, hex.EncodeToString(v))))
} }
@ -187,6 +173,6 @@ func parseConfigPair(kvStr string, force bool) (key string, val any, err error)
return return
} }
func invalidConfigValueErr(key []byte) error { func invalidConfigValueErr(key string) error {
return fmt.Errorf("invalid %s config value from netmap contract", key) return fmt.Errorf("invalid %s config value from netmap contract", key)
} }

View file

@ -23,6 +23,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/rpcclient"
"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/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
@ -30,8 +31,8 @@ import (
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode" "github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate" "github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
"github.com/spf13/viper"
) )
const ( const (
@ -85,6 +86,21 @@ var (
nnsContract, nnsContract,
alphabetContract, alphabetContract,
}, contractList...) }, contractList...)
netmapConfigKeys = []string{
netmapEpochKey,
netmapMaxObjectSizeKey,
netmapAuditFeeKey,
netmapContainerFeeKey,
netmapContainerAliasFeeKey,
netmapEigenTrustIterationsKey,
netmapEigenTrustAlphaKey,
netmapBasicIncomeRateKey,
netmapInnerRingCandidateFeeKey,
netmapWithdrawFeeKey,
netmapHomomorphicHashDisabledKey,
netmapMaintenanceAllowedKey,
}
) )
type contractState struct { type contractState struct {
@ -239,7 +255,7 @@ func (c *initializeContext) deployOrUpdateContracts(w *io2.BufBinWriter, nnsHash
invokeHash = ctrHash invokeHash = ctrHash
} }
params := getContractDeployParameters(cs, c.getContractDeployData(ctrName, keysParam)) params := getContractDeployParameters(cs, c.getContractDeployData(ctrName, keysParam, updateMethodName))
res, err := c.CommitteeAct.MakeCall(invokeHash, method, params...) res, err := c.CommitteeAct.MakeCall(invokeHash, method, params...)
if err != nil { if err != nil {
if method != updateMethodName || !strings.Contains(err.Error(), common.ErrAlreadyUpdated) { if method != updateMethodName || !strings.Contains(err.Error(), common.ErrAlreadyUpdated) {
@ -362,7 +378,7 @@ func (c *initializeContext) deployContracts() error {
return fmt.Errorf("can't sign manifest group: %v", err) return fmt.Errorf("can't sign manifest group: %v", err)
} }
params := getContractDeployParameters(cs, c.getContractDeployData(ctrName, keysParam)) params := getContractDeployParameters(cs, c.getContractDeployData(ctrName, keysParam, deployMethodName))
res, err := c.CommitteeAct.MakeCall(management.Hash, deployMethodName, params...) res, err := c.CommitteeAct.MakeCall(management.Hash, deployMethodName, params...)
if err != nil { if err != nil {
return fmt.Errorf("can't deploy %s contract: %w", ctrName, err) return fmt.Errorf("can't deploy %s contract: %w", ctrName, err)
@ -529,7 +545,7 @@ func getContractDeployParameters(cs *contractState, deployData []any) []any {
return []any{cs.RawNEF, cs.RawManifest, deployData} return []any{cs.RawNEF, cs.RawManifest, deployData}
} }
func (c *initializeContext) getContractDeployData(ctrName string, keysParam []any) []any { func (c *initializeContext) getContractDeployData(ctrName string, keysParam []any, method string) []any {
items := make([]any, 1, 6) items := make([]any, 1, 6)
items[0] = false // notaryDisabled is false items[0] = false // notaryDisabled is false
@ -566,20 +582,31 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []an
c.Contracts[netmapContract].Hash, c.Contracts[netmapContract].Hash,
c.Contracts[containerContract].Hash) c.Contracts[containerContract].Hash)
case netmapContract: case netmapContract:
configParam := []any{ md := getDefaultNetmapContractConfigMap()
netmapEpochKey, viper.GetInt64(epochDurationInitFlag), if method == updateMethodName {
netmapMaxObjectSizeKey, viper.GetInt64(maxObjectSizeInitFlag), arr, err := c.getNetConfigFromNetmapContract()
netmapAuditFeeKey, viper.GetInt64(auditFeeInitFlag), if err != nil {
netmapContainerFeeKey, viper.GetInt64(containerFeeInitFlag), panic(err)
netmapContainerAliasFeeKey, viper.GetInt64(containerAliasFeeInitFlag), }
netmapEigenTrustIterationsKey, int64(defaultEigenTrustIterations), m, err := parseConfigFromNetmapContract(arr)
netmapEigenTrustAlphaKey, defaultEigenTrustAlpha, if err != nil {
netmapBasicIncomeRateKey, viper.GetInt64(incomeRateInitFlag), panic(err)
netmapInnerRingCandidateFeeKey, viper.GetInt64(candidateFeeInitFlag), }
netmapWithdrawFeeKey, viper.GetInt64(withdrawFeeInitFlag), for k, v := range m {
netmapHomomorphicHashDisabledKey, viper.GetBool(homomorphicHashDisabledInitFlag), for _, key := range netmapConfigKeys {
netmapMaintenanceAllowedKey, viper.GetBool(maintenanceModeAllowedInitFlag), if k == key {
md[k] = v
break
}
}
}
} }
var configParam []any
for k, v := range md {
configParam = append(configParam, k, v)
}
items = append(items, items = append(items,
c.Contracts[balanceContract].Hash, c.Contracts[balanceContract].Hash,
c.Contracts[containerContract].Hash, c.Contracts[containerContract].Hash,
@ -595,6 +622,22 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []an
return items return items
} }
func (c *initializeContext) getNetConfigFromNetmapContract() ([]stackitem.Item, error) {
cs, err := c.Client.GetContractStateByID(1)
if err != nil {
return nil, fmt.Errorf("NNS is not yet deployed: %w", err)
}
nmHash, err := nnsResolveHash(c.ReadOnlyInvoker, cs.Hash, netmapContract+".frostfs")
if err != nil {
return nil, fmt.Errorf("can't get netmap contract hash: %w", err)
}
arr, err := unwrap.Array(c.ReadOnlyInvoker.Call(nmHash, "listConfig"))
if err != nil {
return nil, fmt.Errorf("can't fetch list of network config keys from the netmap contract")
}
return arr, err
}
func (c *initializeContext) getAlphabetDeployItems(i, n int) []any { func (c *initializeContext) getAlphabetDeployItems(i, n int) []any {
items := make([]any, 6) items := make([]any, 6)
items[0] = false items[0] = false

View file

@ -0,0 +1,47 @@
package morph
import (
"errors"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/spf13/viper"
)
func getDefaultNetmapContractConfigMap() map[string]any {
m := make(map[string]any)
m[netmapEpochKey] = viper.GetInt64(epochDurationInitFlag)
m[netmapMaxObjectSizeKey] = viper.GetInt64(maxObjectSizeInitFlag)
m[netmapAuditFeeKey] = viper.GetInt64(auditFeeInitFlag)
m[netmapContainerFeeKey] = viper.GetInt64(containerFeeInitFlag)
m[netmapContainerAliasFeeKey] = viper.GetInt64(containerAliasFeeInitFlag)
m[netmapEigenTrustIterationsKey] = int64(defaultEigenTrustIterations)
m[netmapEigenTrustAlphaKey] = defaultEigenTrustAlpha
m[netmapBasicIncomeRateKey] = viper.GetInt64(incomeRateInitFlag)
m[netmapInnerRingCandidateFeeKey] = viper.GetInt64(candidateFeeInitFlag)
m[netmapWithdrawFeeKey] = viper.GetInt64(withdrawFeeInitFlag)
m[netmapHomomorphicHashDisabledKey] = viper.GetBool(homomorphicHashDisabledInitFlag)
m[netmapMaintenanceAllowedKey] = viper.GetBool(maintenanceModeAllowedInitFlag)
return m
}
func parseConfigFromNetmapContract(arr []stackitem.Item) (map[string][]byte, error) {
m := make(map[string][]byte, len(arr))
for _, param := range arr {
tuple, ok := param.Value().([]stackitem.Item)
if !ok || len(tuple) != 2 {
return nil, errors.New("invalid ListConfig response from netmap contract")
}
k, err := tuple[0].TryBytes()
if err != nil {
return nil, errors.New("invalid config key from netmap contract")
}
v, err := tuple[1].TryBytes()
if err != nil {
return nil, invalidConfigValueErr(string(k))
}
m[string(k)] = v
}
return m, nil
}