Skip to content

Commit

Permalink
Merge pull request #107 from nspcc-dev/103-make-it-single-network-per…
Browse files Browse the repository at this point in the history
…-chain
  • Loading branch information
cthulhu-rider authored Dec 29, 2023
2 parents 78b6a6f + dde8558 commit 935a88c
Show file tree
Hide file tree
Showing 12 changed files with 659 additions and 697 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@ Changelog for NeoFS Monitor

### Changed
- Usage of Locode DB Go package (#100)
- Configuration supports only one chain in a moment (#103)

### Removed
- Locode DB configuration options (#100)

### Upgrading from v0.9.5

The configuration sections `mainnet` and `morph` were replaced with similar `chain` sections. To choice between
main (Neo) chain and side (NeoFS) chain, use `chain.fschain` option. If true, monitor connects to the NeoFS chain,
otherwise, to the Neo chain.

## [0.9.5] - 2022-12-29

### Changed
Expand Down
12 changes: 5 additions & 7 deletions cmd/neofs-net-monitor/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ const (
cfgNeoFSContract = "contracts.neofs"

// neo rpc node related config values
mainPrefix = "mainnet"
sidePrefix = "morph"
prefix = "chain"

cfgChainFSChain = "chain.fschain"

cfgNeoRPCEndpoint = "rpc.endpoint"
cfgNeoRPCDialTimeout = "rpc.dial_timeout"
Expand All @@ -31,11 +32,8 @@ const (
)

func DefaultConfiguration(cfg *viper.Viper) {
cfg.SetDefault(sidePrefix+delimiter+cfgNeoRPCEndpoint, "")
cfg.SetDefault(sidePrefix+delimiter+cfgNeoRPCDialTimeout, 5*time.Second)

cfg.SetDefault(mainPrefix+delimiter+cfgNeoRPCEndpoint, "")
cfg.SetDefault(mainPrefix+delimiter+cfgNeoRPCDialTimeout, 5*time.Second)
cfg.SetDefault(prefix+delimiter+cfgNeoRPCEndpoint, "")
cfg.SetDefault(prefix+delimiter+cfgNeoRPCDialTimeout, 5*time.Second)

cfg.SetDefault(cfgMetricsEndpoint, ":16512")
cfg.SetDefault(cfgMetricsInterval, 15*time.Minute)
Expand Down
136 changes: 74 additions & 62 deletions cmd/neofs-net-monitor/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,9 @@ func New(ctx context.Context, cfg *viper.Viper) (*monitor.Monitor, error) {
return nil, err
}

sideChainEndpoints := cfg.GetStringSlice(sidePrefix + delimiter + cfgNeoRPCEndpoint)
sideChainTimeout := cfg.GetDuration(sidePrefix + delimiter + cfgNeoRPCDialTimeout)
sideChainRecheck := cfg.GetDuration(sidePrefix + delimiter + cfgNeoRPCRecheckInterval)

mainChainEndpoints := cfg.GetStringSlice(mainPrefix + delimiter + cfgNeoRPCEndpoint)
mainChainTimeout := cfg.GetDuration(mainPrefix + delimiter + cfgNeoRPCDialTimeout)
mainChainRecheck := cfg.GetDuration(mainPrefix + delimiter + cfgNeoRPCRecheckInterval)
sideChainEndpoints := cfg.GetStringSlice(prefix + delimiter + cfgNeoRPCEndpoint)
sideChainTimeout := cfg.GetDuration(prefix + delimiter + cfgNeoRPCDialTimeout)
sideChainRecheck := cfg.GetDuration(prefix + delimiter + cfgNeoRPCRecheckInterval)

sideNeogoClient, err := pool.NewPool(ctx, pool.PrmPool{
Endpoints: sideChainEndpoints,
Expand All @@ -40,109 +36,125 @@ func New(ctx context.Context, cfg *viper.Viper) (*monitor.Monitor, error) {
return nil, fmt.Errorf("can't create side chain neo-go client: %w", err)
}

mainNeogoClient, err := pool.NewPool(ctx, pool.PrmPool{
Endpoints: mainChainEndpoints,
DialTimeout: mainChainTimeout,
RecheckInterval: mainChainRecheck,
})
var job monitor.Job
if cfg.GetBool(cfgChainFSChain) {
monitor.RegisterSideChainMetrics()
job, err = sideChainJob(ctx, cfg, sideNeogoClient, logger, sideChainEndpoints)
} else {
monitor.RegisterMainChainMetrics()
job, err = mainChainJob(cfg, sideNeogoClient, logger)
}

if err != nil {
return nil, fmt.Errorf("can't create main chain neo-go client: %w", err)
return nil, err
}

return monitor.New(
job,
cfg.GetString(cfgMetricsEndpoint),
cfg.GetDuration(cfgMetricsInterval),
logger,
), nil
}

func mainChainJob(cfg *viper.Viper, neogoClient *pool.Pool, logger *zap.Logger) (*monitor.MainJob, error) {
alphabetFetcher := morphchain.NewMainChainAlphabetFetcher(neogoClient)

balanceFetcher, err := morphchain.NewBalanceFetcher(
morphchain.BalanceFetcherArgs{
Cli: neogoClient,
})
if err != nil {
return nil, fmt.Errorf("can't initialize Neo chain balance reader: %w", err)
}

var neofs *util.Uint160

neofsContract := cfg.GetString(cfgNeoFSContract)
if len(neofsContract) != 0 {
sh, err := util.Uint160DecodeStringLE(neofsContract)
if err != nil {
return nil, fmt.Errorf("decode configured NeoFS contract address %q: %w", cfgNeoFSContract, err)
}
neofs = &sh
} else {
logger.Info("NeoFS contract address not configured, continue without it")
}

netmapContract, err := sideNeogoClient.ResolveContract(rpcnns.NameNetmap)
return monitor.NewMainJob(monitor.MainJobArgs{
AlphabetFetcher: alphabetFetcher,
BalanceFetcher: balanceFetcher,
Neofs: neofs,
Logger: logger,
}), nil
}

func sideChainJob(ctx context.Context, cfg *viper.Viper, neogoClient *pool.Pool, logger *zap.Logger, sideChainEndpoints []string) (*monitor.SideJob, error) {
netmapContract, err := neogoClient.ResolveContract(rpcnns.NameNetmap)
if err != nil {
return nil, fmt.Errorf("can't read netmap scripthash: %w", err)
}

containerContract, err := sideNeogoClient.ResolveContract(rpcnns.NameContainer)
containerContract, err := neogoClient.ResolveContract(rpcnns.NameContainer)
if err != nil {
return nil, fmt.Errorf("can't read container scripthash: %w", err)
}

nmFetcher, err := contracts.NewNetmap(contracts.NetmapArgs{
Pool: sideNeogoClient,
Pool: neogoClient,
NetmapContract: netmapContract,
Logger: logger,
})
if err != nil {
return nil, fmt.Errorf("can't initialize netmap fetcher: %w", err)
}

cnrFetcher, err := contracts.NewContainer(sideNeogoClient, containerContract)
cnrFetcher, err := contracts.NewContainer(neogoClient, containerContract)
if err != nil {
return nil, fmt.Errorf("can't initialize container fetcher: %w", err)
}

alphabetFetcher, err := morphchain.NewAlphabetFetcher(morphchain.AlphabetFetcherArgs{
Committeer: sideNeogoClient,
Designater: mainNeogoClient,
})
if err != nil {
return nil, fmt.Errorf("can't initialize alphabet fetcher: %w", err)
}
alphabetFetcher := morphchain.NewSideChainAlphabetFetcher(neogoClient)

sideBalanceFetcher, err := morphchain.NewBalanceFetcher(morphchain.BalanceFetcherArgs{
Cli: sideNeogoClient,
balanceFetcher, err := morphchain.NewBalanceFetcher(morphchain.BalanceFetcherArgs{
Cli: neogoClient,
})
if err != nil {
return nil, fmt.Errorf("can't initialize side balance fetcher: %w", err)
}

mainBalanceFetcher, err := morphchain.NewBalanceFetcher(morphchain.BalanceFetcherArgs{
Cli: mainNeogoClient,
})
if err != nil {
return nil, fmt.Errorf("can't initialize main balance fetcher: %w", err)
}

var (
balance util.Uint160
proxy *util.Uint160
neofs *util.Uint160
)

balance, err = sideNeogoClient.ResolveContract(rpcnns.NameBalance)
balance, err = neogoClient.ResolveContract(rpcnns.NameBalance)
if err != nil {
return nil, fmt.Errorf("balance contract is not available: %w", err)
}

proxyContract, err := sideNeogoClient.ResolveContract(rpcnns.NameProxy)
proxyContract, err := neogoClient.ResolveContract(rpcnns.NameProxy)
if err != nil {
logger.Info("proxy disabled")
} else {
proxy = &proxyContract
}

neofsContract := cfg.GetString(cfgNeoFSContract)
if len(neofsContract) != 0 {
sh, err := util.Uint160DecodeStringLE(neofsContract)
if err != nil {
return nil, fmt.Errorf("NNS u160 decode: %w", err)
}
neofs = &sh
} else {
logger.Info("neofs contract ignored")
}

mnPool := multinodepool.NewPool(sideChainEndpoints, cfg.GetDuration(cfgMetricsInterval))
if err = mnPool.Dial(ctx); err != nil {
return nil, fmt.Errorf("multinodepool: %w", err)
}

return monitor.New(monitor.Args{
Balance: balance,
Proxy: proxy,
Neofs: neofs,
Logger: logger,
Sleep: cfg.GetDuration(cfgMetricsInterval),
MetricsAddress: cfg.GetString(cfgMetricsEndpoint),
AlpFetcher: alphabetFetcher,
NmFetcher: nmFetcher,
IRFetcher: nmFetcher,
SideBlFetcher: sideBalanceFetcher,
MainBlFetcher: mainBalanceFetcher,
CnrFetcher: cnrFetcher,
HeightFetcher: mnPool,
StateFetcher: mnPool,
return monitor.NewSideJob(monitor.SideJobArgs{
Logger: logger,
Balance: balance,
Proxy: proxy,
AlphabetFetcher: alphabetFetcher,
NmFetcher: nmFetcher,
IRFetcher: nmFetcher,
BalanceFetcher: balanceFetcher,
CnrFetcher: cnrFetcher,
HeightFetcher: mnPool,
StateFetcher: mnPool,
}), nil
}
15 changes: 4 additions & 11 deletions config/config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Mainchain NEO RPC related configuration.
mainnet:
# Neo RPC related configuration.
chain:
# If true, monitor connects to the NeoFS chain, otherwise, to the Neo chain.
fschain: false
rpc:
dial_timeout: 5s
# stores the interval after which a current connection health check is performed.
Expand All @@ -8,15 +10,6 @@ mainnet:
- https://rpc1.t5.n3.nspcc.ru:21331
- https://rpc2.t5.n3.nspcc.ru:21331

# Sidechain NEO RPC related configuration.
morph:
rpc:
dial_timeout: 5s
health_recheck_interval: 5s
endpoint:
- https://rpc1.morph.t5.fs.neo.org:51331
- https://rpc2.morph.t5.fs.neo.org:51331

# Prometheus metric configuration.
metrics:
# Interval between NeoFS metric scrapping.
Expand Down
79 changes: 79 additions & 0 deletions pkg/monitor/main_job.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package monitor

import (
"encoding/hex"

"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/util"
"go.uber.org/zap"
)

type (
MainJobArgs struct {
AlphabetFetcher AlphabetFetcher
BalanceFetcher BalanceFetcher
Neofs *util.Uint160
Logger *zap.Logger
}

MainJob struct {
alphabetFetcher AlphabetFetcher
balanceFetcher BalanceFetcher
logger *zap.Logger
neofs *util.Uint160
}
)

func NewMainJob(args MainJobArgs) *MainJob {
return &MainJob{
alphabetFetcher: args.AlphabetFetcher,
balanceFetcher: args.BalanceFetcher,
logger: args.Logger,
neofs: args.Neofs,
}
}

func (m *MainJob) Process() {
if mainAlphabet, err := m.alphabetFetcher.FetchAlphabet(); err != nil {
m.logger.Warn("can't read NeoFS Aphabet members", zap.Error(err))
} else {
processAlphabetPublicKeys(mainAlphabet)
m.processMainAlphabet(mainAlphabet)
}

m.processMainChainSupply()
}

func (m *MainJob) processMainAlphabet(alphabet keys.PublicKeys) {
exportGasBalances := make(map[string]int64, len(alphabet))

for _, key := range alphabet {
keyHex := hex.EncodeToString(key.Bytes())

balanceGAS, err := m.balanceFetcher.FetchGAS(*key)
if err != nil {
m.logger.Debug("can't fetch gas balance", zap.String("key", keyHex), zap.Error(err))
} else {
exportGasBalances[keyHex] = balanceGAS
}
}

alphabetGASBalances.Reset()
for k, v := range exportGasBalances {
alphabetGASBalances.WithLabelValues(k).Set(float64(v))
}
}

func (m *MainJob) processMainChainSupply() {
if m.neofs == nil {
return
}

balance, err := m.balanceFetcher.FetchGASByScriptHash(*m.neofs)
if err != nil {
m.logger.Debug("can't fetch NeoFS contract's GAS balance", zap.Error(err))
return
}

mainChainSupply.Set(float64(balance))
}
Loading

0 comments on commit 935a88c

Please sign in to comment.