2021-08-31 13:02:15 +00:00
|
|
|
package innerring
|
|
|
|
|
|
|
|
import (
|
2021-10-20 13:21:40 +00:00
|
|
|
"errors"
|
2021-08-31 13:02:15 +00:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
2023-03-07 13:38:26 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
2021-08-31 13:02:15 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
|
|
"github.com/spf13/viper"
|
|
|
|
)
|
|
|
|
|
|
|
|
type contracts struct {
|
2022-12-23 17:35:35 +00:00
|
|
|
frostfs util.Uint160 // in mainnet
|
2021-08-31 13:02:15 +00:00
|
|
|
netmap util.Uint160 // in morph
|
|
|
|
balance util.Uint160 // in morph
|
|
|
|
container util.Uint160 // in morph
|
|
|
|
proxy util.Uint160 // in morph
|
|
|
|
processing util.Uint160 // in mainnet
|
2022-12-23 17:35:35 +00:00
|
|
|
frostfsID util.Uint160 // in morph
|
2021-08-31 13:02:15 +00:00
|
|
|
|
2023-04-26 07:51:30 +00:00
|
|
|
alphabet AlphabetContracts // in morph
|
2021-08-31 13:02:15 +00:00
|
|
|
}
|
|
|
|
|
2023-04-25 13:34:15 +00:00
|
|
|
func parseContracts(cfg *viper.Viper, morph nnsResolver, withoutMainNet, withoutMainNotary, withoutSideNotary bool) (*contracts, error) {
|
2021-08-31 13:02:15 +00:00
|
|
|
var (
|
|
|
|
result = new(contracts)
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
|
|
|
|
if !withoutMainNet {
|
2022-12-23 17:35:35 +00:00
|
|
|
result.frostfs, err = util.Uint160DecodeStringLE(cfg.GetString("contracts.frostfs"))
|
2021-08-31 13:02:15 +00:00
|
|
|
if err != nil {
|
2022-12-23 17:35:35 +00:00
|
|
|
return nil, fmt.Errorf("can't get frostfs script hash: %w", err)
|
2021-08-31 13:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if !withoutMainNotary {
|
|
|
|
result.processing, err = util.Uint160DecodeStringLE(cfg.GetString("contracts.processing"))
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("can't get processing script hash: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !withoutSideNotary {
|
|
|
|
result.proxy, err = parseContract(cfg, morph, "contracts.proxy", client.NNSProxyContractName)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("can't get proxy script hash: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
targets := [...]struct {
|
|
|
|
cfgName string
|
|
|
|
nnsName string
|
|
|
|
dest *util.Uint160
|
|
|
|
}{
|
|
|
|
{"contracts.netmap", client.NNSNetmapContractName, &result.netmap},
|
|
|
|
{"contracts.balance", client.NNSBalanceContractName, &result.balance},
|
|
|
|
{"contracts.container", client.NNSContainerContractName, &result.container},
|
2023-01-10 13:07:47 +00:00
|
|
|
{"contracts.frostfsid", client.NNSFrostFSIDContractName, &result.frostfsID},
|
2021-08-31 13:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, t := range targets {
|
|
|
|
*t.dest, err = parseContract(cfg, morph, t.cfgName, t.nnsName)
|
|
|
|
if err != nil {
|
|
|
|
name := strings.TrimPrefix(t.cfgName, "contracts.")
|
|
|
|
return nil, fmt.Errorf("can't get %s script hash: %w", name, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result.alphabet, err = parseAlphabetContracts(cfg, morph)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
2023-04-26 07:51:30 +00:00
|
|
|
func parseAlphabetContracts(cfg *viper.Viper, morph nnsResolver) (AlphabetContracts, error) {
|
2021-08-31 13:02:15 +00:00
|
|
|
num := GlagoliticLetter(cfg.GetUint("contracts.alphabet.amount"))
|
2023-04-26 07:51:30 +00:00
|
|
|
alpha := NewAlphabetContracts()
|
2021-08-31 13:02:15 +00:00
|
|
|
|
|
|
|
if num > lastLetterNum {
|
|
|
|
return nil, fmt.Errorf("amount of alphabet contracts overflows glagolitsa %d > %d", num, lastLetterNum)
|
|
|
|
}
|
|
|
|
|
2021-10-20 13:21:40 +00:00
|
|
|
thresholdIsSet := num != 0
|
|
|
|
|
|
|
|
if !thresholdIsSet {
|
|
|
|
// try to read maximum alphabet contracts
|
|
|
|
// if threshold has not been set manually
|
|
|
|
num = lastLetterNum
|
|
|
|
}
|
|
|
|
|
2021-08-31 13:02:15 +00:00
|
|
|
for letter := az; letter < num; letter++ {
|
|
|
|
contractHash, err := parseContract(cfg, morph,
|
|
|
|
"contracts.alphabet."+letter.String(),
|
|
|
|
client.NNSAlphabetContractName(int(letter)),
|
|
|
|
)
|
|
|
|
if err != nil {
|
2021-10-20 13:21:40 +00:00
|
|
|
if errors.Is(err, client.ErrNNSRecordNotFound) {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
2021-08-31 13:02:15 +00:00
|
|
|
return nil, fmt.Errorf("invalid alphabet %s contract: %w", letter, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
alpha.set(letter, contractHash)
|
|
|
|
}
|
|
|
|
|
2021-10-20 13:21:40 +00:00
|
|
|
if thresholdIsSet && len(alpha) != int(num) {
|
|
|
|
return nil, fmt.Errorf("could not read all contracts: required %d, read %d", num, len(alpha))
|
|
|
|
}
|
|
|
|
|
2021-08-31 13:02:15 +00:00
|
|
|
return alpha, nil
|
|
|
|
}
|
|
|
|
|
2023-04-25 13:34:15 +00:00
|
|
|
func parseContract(cfg *viper.Viper, morph nnsResolver, cfgName, nnsName string) (res util.Uint160, err error) {
|
2021-08-31 13:02:15 +00:00
|
|
|
contractStr := cfg.GetString(cfgName)
|
|
|
|
if len(contractStr) == 0 {
|
|
|
|
return morph.NNSContractAddress(nnsName)
|
|
|
|
}
|
|
|
|
|
|
|
|
return util.Uint160DecodeStringLE(contractStr)
|
|
|
|
}
|
2023-04-25 13:34:15 +00:00
|
|
|
|
|
|
|
type nnsResolver interface {
|
|
|
|
NNSContractAddress(name string) (sh util.Uint160, err error)
|
|
|
|
}
|