forked from TrueCloudLab/frostfs-node
Add Inner Ring code
This commit is contained in:
parent
dadfd90dcd
commit
b7b5079934
400 changed files with 11420 additions and 8690 deletions
69
cmd/neofs-node/modules/morph/balance.go
Normal file
69
cmd/neofs-node/modules/morph/balance.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package morph
|
||||
|
||||
import (
|
||||
contract "github.com/nspcc-dev/neofs-node/pkg/morph/client/balance"
|
||||
clientWrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/balance/wrapper"
|
||||
accounting "github.com/nspcc-dev/neofs-node/pkg/network/transport/accounting/grpc"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/dig"
|
||||
)
|
||||
|
||||
type balanceContractResult struct {
|
||||
dig.Out
|
||||
|
||||
Client *clientWrapper.Wrapper
|
||||
|
||||
AccountingService accounting.Service
|
||||
}
|
||||
|
||||
// BalanceContractName is a name of Balance contract config sub-section.
|
||||
const BalanceContractName = "balance"
|
||||
|
||||
const (
|
||||
balanceContractBalanceOfOpt = "balance_of_method"
|
||||
|
||||
balanceContractDecimalsOfOpt = "decimals_method"
|
||||
)
|
||||
|
||||
// BalanceContractBalanceOfOptPath is a path to balanceOf method name option.
|
||||
func BalanceContractBalanceOfOptPath() string {
|
||||
return optPath(prefix, BalanceContractName, balanceContractBalanceOfOpt)
|
||||
}
|
||||
|
||||
// BalanceContractDecimalsOfOptPath is a path to decimals method name option.
|
||||
func BalanceContractDecimalsOfOptPath() string {
|
||||
return optPath(prefix, BalanceContractName, balanceContractDecimalsOfOpt)
|
||||
}
|
||||
|
||||
func newBalanceContract(p contractParams) (res balanceContractResult, err error) {
|
||||
client, ok := p.MorphContracts[BalanceContractName]
|
||||
if !ok {
|
||||
err = errors.Errorf("missing %s contract client", BalanceContractName)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
balanceOfMethod = p.Viper.GetString(BalanceContractBalanceOfOptPath())
|
||||
decimalsMethod = p.Viper.GetString(BalanceContractDecimalsOfOptPath())
|
||||
)
|
||||
|
||||
var c *contract.Client
|
||||
if c, err = contract.New(client,
|
||||
contract.WithBalanceOfMethod(balanceOfMethod),
|
||||
contract.WithDecimalsMethod(decimalsMethod),
|
||||
); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if res.Client, err = clientWrapper.New(c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if res.AccountingService, err = accounting.New(accounting.Params{
|
||||
ContractClient: res.Client,
|
||||
}); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
138
cmd/neofs-node/modules/morph/common.go
Normal file
138
cmd/neofs-node/modules/morph/common.go
Normal file
|
@ -0,0 +1,138 @@
|
|||
package morph
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/core/netmap"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/dig"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// SmartContracts maps smart contract name to contract client.
|
||||
type SmartContracts map[string]*client.StaticClient
|
||||
|
||||
// EventHandlers maps notification event name to handler information.
|
||||
type EventHandlers map[string]event.HandlerInfo
|
||||
|
||||
type morphContractsParams struct {
|
||||
dig.In
|
||||
|
||||
Viper *viper.Viper
|
||||
|
||||
Client *client.Client
|
||||
|
||||
Listener event.Listener
|
||||
}
|
||||
|
||||
type contractParams struct {
|
||||
dig.In
|
||||
|
||||
Viper *viper.Viper
|
||||
|
||||
Logger *zap.Logger
|
||||
|
||||
MorphContracts SmartContracts
|
||||
|
||||
NodeInfo netmap.Info
|
||||
}
|
||||
|
||||
func newMorphContracts(p morphContractsParams) (SmartContracts, EventHandlers, error) {
|
||||
mContracts := make(map[string]*client.StaticClient, len(ContractNames))
|
||||
mHandlers := make(map[string]event.HandlerInfo)
|
||||
|
||||
for _, contractName := range ContractNames {
|
||||
scHash, err := util.Uint160DecodeStringLE(
|
||||
p.Viper.GetString(
|
||||
ScriptHashOptPath(contractName),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
fee := util.Fixed8FromInt64(
|
||||
p.Viper.GetInt64(
|
||||
InvocationFeeOptPath(contractName),
|
||||
),
|
||||
)
|
||||
|
||||
mContracts[contractName], err = client.NewStatic(p.Client, scHash, fee)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// set event parsers
|
||||
parserInfo := event.ParserInfo{}
|
||||
parserInfo.SetScriptHash(scHash)
|
||||
|
||||
handlerInfo := event.HandlerInfo{}
|
||||
handlerInfo.SetScriptHash(scHash)
|
||||
|
||||
for _, item := range mParsers[contractName] {
|
||||
parserInfo.SetParser(item.parser)
|
||||
|
||||
optPath := ContractEventOptPath(contractName, item.typ)
|
||||
|
||||
typEvent := event.TypeFromString(
|
||||
p.Viper.GetString(optPath),
|
||||
)
|
||||
|
||||
parserInfo.SetType(typEvent)
|
||||
handlerInfo.SetType(typEvent)
|
||||
|
||||
p.Listener.SetParser(parserInfo)
|
||||
|
||||
mHandlers[optPath] = handlerInfo
|
||||
}
|
||||
}
|
||||
|
||||
return mContracts, mHandlers, nil
|
||||
}
|
||||
|
||||
const prefix = "morph"
|
||||
|
||||
const (
|
||||
endpointOpt = "endpoint"
|
||||
|
||||
dialTimeoutOpt = "dial_timeout"
|
||||
|
||||
magicNumberOpt = "magic_number"
|
||||
|
||||
scriptHashOpt = "script_hash"
|
||||
|
||||
invocationFeeOpt = "invocation_fee"
|
||||
)
|
||||
|
||||
// ContractNames is a list of smart contract names.
|
||||
var ContractNames = []string{
|
||||
containerContractName,
|
||||
NetmapContractName,
|
||||
BalanceContractName,
|
||||
}
|
||||
|
||||
// EndpointOptPath returns the config path to goclient endpoint.
|
||||
func EndpointOptPath() string {
|
||||
return optPath(prefix, endpointOpt)
|
||||
}
|
||||
|
||||
// MagicNumberOptPath returns the config path to goclient magic number.
|
||||
func MagicNumberOptPath() string {
|
||||
return optPath(prefix, magicNumberOpt)
|
||||
}
|
||||
|
||||
// DialTimeoutOptPath returns the config path to goclient dial timeout.
|
||||
func DialTimeoutOptPath() string {
|
||||
return optPath(prefix, dialTimeoutOpt)
|
||||
}
|
||||
|
||||
// ScriptHashOptPath calculates the config path to script hash config of particular contract.
|
||||
func ScriptHashOptPath(name string) string {
|
||||
return optPath(prefix, name, scriptHashOpt)
|
||||
}
|
||||
|
||||
// InvocationFeeOptPath calculates the config path to invocation fee config of particular contract.
|
||||
func InvocationFeeOptPath(name string) string {
|
||||
return optPath(prefix, name, invocationFeeOpt)
|
||||
}
|
103
cmd/neofs-node/modules/morph/container.go
Normal file
103
cmd/neofs-node/modules/morph/container.go
Normal file
|
@ -0,0 +1,103 @@
|
|||
package morph
|
||||
|
||||
import (
|
||||
eacl "github.com/nspcc-dev/neofs-node/pkg/core/container/acl/extended/storage"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/core/container/storage"
|
||||
contract "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
|
||||
clientWrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/dig"
|
||||
)
|
||||
|
||||
type containerContractResult struct {
|
||||
dig.Out
|
||||
|
||||
ExtendedACLStore eacl.Storage
|
||||
|
||||
ContainerStorage storage.Storage
|
||||
}
|
||||
|
||||
const (
|
||||
containerContractName = "container"
|
||||
|
||||
containerContractSetEACLOpt = "set_eacl_method"
|
||||
|
||||
containerContractEACLOpt = "get_eacl_method"
|
||||
|
||||
containerContractPutOpt = "put_method"
|
||||
|
||||
containerContractGetOpt = "get_method"
|
||||
|
||||
containerContractDelOpt = "delete_method"
|
||||
|
||||
containerContractListOpt = "list_method"
|
||||
)
|
||||
|
||||
// ContainerContractSetEACLOptPath returns the config path to set eACL method name of Container contract.
|
||||
func ContainerContractSetEACLOptPath() string {
|
||||
return optPath(prefix, containerContractName, containerContractSetEACLOpt)
|
||||
}
|
||||
|
||||
// ContainerContractEACLOptPath returns the config path to get eACL method name of Container contract.
|
||||
func ContainerContractEACLOptPath() string {
|
||||
return optPath(prefix, containerContractName, containerContractEACLOpt)
|
||||
}
|
||||
|
||||
// ContainerContractPutOptPath returns the config path to put container method name of Container contract.
|
||||
func ContainerContractPutOptPath() string {
|
||||
return optPath(prefix, containerContractName, containerContractPutOpt)
|
||||
}
|
||||
|
||||
// ContainerContractGetOptPath returns the config path to get container method name of Container contract.
|
||||
func ContainerContractGetOptPath() string {
|
||||
return optPath(prefix, containerContractName, containerContractGetOpt)
|
||||
}
|
||||
|
||||
// ContainerContractDelOptPath returns the config path to delete container method name of Container contract.
|
||||
func ContainerContractDelOptPath() string {
|
||||
return optPath(prefix, containerContractName, containerContractDelOpt)
|
||||
}
|
||||
|
||||
// ContainerContractListOptPath returns the config path to list containers method name of Container contract.
|
||||
func ContainerContractListOptPath() string {
|
||||
return optPath(prefix, containerContractName, containerContractListOpt)
|
||||
}
|
||||
|
||||
func newContainerContract(p contractParams) (res containerContractResult, err error) {
|
||||
client, ok := p.MorphContracts[containerContractName]
|
||||
if !ok {
|
||||
err = errors.Errorf("missing %s contract client", containerContractName)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
setEACLMethod = p.Viper.GetString(ContainerContractSetEACLOptPath())
|
||||
eaclMethod = p.Viper.GetString(ContainerContractEACLOptPath())
|
||||
getMethod = p.Viper.GetString(ContainerContractGetOptPath())
|
||||
putMethod = p.Viper.GetString(ContainerContractPutOptPath())
|
||||
deleteMethod = p.Viper.GetString(ContainerContractDelOptPath())
|
||||
listMethod = p.Viper.GetString(ContainerContractListOptPath())
|
||||
)
|
||||
|
||||
var containerClient *contract.Client
|
||||
if containerClient, err = contract.New(client,
|
||||
contract.WithSetEACLMethod(setEACLMethod),
|
||||
contract.WithEACLMethod(eaclMethod),
|
||||
contract.WithGetMethod(getMethod),
|
||||
contract.WithPutMethod(putMethod),
|
||||
contract.WithDeleteMethod(deleteMethod),
|
||||
contract.WithListMethod(listMethod),
|
||||
); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var wrapClient *clientWrapper.Wrapper
|
||||
if wrapClient, err = clientWrapper.New(containerClient); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
res.ContainerStorage = wrapClient
|
||||
res.ExtendedACLStore = wrapClient
|
||||
|
||||
return res, nil
|
||||
}
|
28
cmd/neofs-node/modules/morph/event.go
Normal file
28
cmd/neofs-node/modules/morph/event.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package morph
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/event/netmap"
|
||||
)
|
||||
|
||||
const eventOpt = "event"
|
||||
|
||||
// NewEpochEventType is a config section of new epoch notification event.
|
||||
const NewEpochEventType = "new_epoch"
|
||||
|
||||
// ContractEventOptPath returns the config path to notification event name of particular contract.
|
||||
func ContractEventOptPath(contract, event string) string {
|
||||
return optPath(prefix, contract, eventOpt, event)
|
||||
}
|
||||
|
||||
var mParsers = map[string][]struct {
|
||||
typ string
|
||||
parser event.Parser
|
||||
}{
|
||||
NetmapContractName: {
|
||||
{
|
||||
typ: NewEpochEventType,
|
||||
parser: netmap.ParseNewEpoch,
|
||||
},
|
||||
},
|
||||
}
|
31
cmd/neofs-node/modules/morph/goclient.go
Normal file
31
cmd/neofs-node/modules/morph/goclient.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package morph
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/dig"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type morphClientParams struct {
|
||||
dig.In
|
||||
|
||||
Viper *viper.Viper
|
||||
|
||||
Logger *zap.Logger
|
||||
|
||||
Key *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
func newClient(p morphClientParams) (*client.Client, error) {
|
||||
return client.New(
|
||||
p.Key,
|
||||
p.Viper.GetString(optPath(prefix, endpointOpt)),
|
||||
client.WithLogger(p.Logger),
|
||||
client.WithDialTimeout(p.Viper.GetDuration(optPath(prefix, dialTimeoutOpt))),
|
||||
client.WithMagic(netmode.Magic(p.Viper.GetUint32(optPath(prefix, magicNumberOpt)))),
|
||||
)
|
||||
}
|
53
cmd/neofs-node/modules/morph/listener.go
Normal file
53
cmd/neofs-node/modules/morph/listener.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package morph
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/subscriber"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/dig"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type eventListenerParams struct {
|
||||
dig.In
|
||||
|
||||
Viper *viper.Viper
|
||||
|
||||
Logger *zap.Logger
|
||||
}
|
||||
|
||||
var listenerPrefix = optPath(prefix, "listener")
|
||||
|
||||
const (
|
||||
listenerEndpointOpt = "endpoint"
|
||||
|
||||
listenerDialTimeoutOpt = "dial_timeout"
|
||||
)
|
||||
|
||||
// ListenerEndpointOptPath returns the config path to event listener's endpoint.
|
||||
func ListenerEndpointOptPath() string {
|
||||
return optPath(listenerPrefix, listenerEndpointOpt)
|
||||
}
|
||||
|
||||
// ListenerDialTimeoutOptPath returns the config path to event listener's dial timeout.
|
||||
func ListenerDialTimeoutOptPath() string {
|
||||
return optPath(listenerPrefix, listenerDialTimeoutOpt)
|
||||
}
|
||||
|
||||
func newEventListener(p eventListenerParams) (event.Listener, error) {
|
||||
sub, err := subscriber.New(context.Background(), &subscriber.Params{
|
||||
Log: p.Logger,
|
||||
Endpoint: p.Viper.GetString(ListenerEndpointOptPath()),
|
||||
DialTimeout: p.Viper.GetDuration(ListenerDialTimeoutOptPath()),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return event.NewListener(event.ListenerParams{
|
||||
Logger: p.Logger,
|
||||
Subscriber: sub,
|
||||
})
|
||||
}
|
21
cmd/neofs-node/modules/morph/module.go
Normal file
21
cmd/neofs-node/modules/morph/module.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package morph
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/fix/module"
|
||||
)
|
||||
|
||||
// Module is a Neo:Morph module.
|
||||
var Module = module.Module{
|
||||
{Constructor: newClient},
|
||||
{Constructor: newMorphContracts},
|
||||
{Constructor: newContainerContract},
|
||||
{Constructor: newNetmapContract},
|
||||
{Constructor: newEventListener},
|
||||
{Constructor: newBalanceContract},
|
||||
}
|
||||
|
||||
func optPath(sections ...string) string {
|
||||
return strings.Join(sections, ".")
|
||||
}
|
94
cmd/neofs-node/modules/morph/netmap.go
Normal file
94
cmd/neofs-node/modules/morph/netmap.go
Normal file
|
@ -0,0 +1,94 @@
|
|||
package morph
|
||||
|
||||
import (
|
||||
contract "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
||||
clientWrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap/wrapper"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/network/bootstrap"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/dig"
|
||||
)
|
||||
|
||||
type netmapContractResult struct {
|
||||
dig.Out
|
||||
|
||||
Client *clientWrapper.Wrapper
|
||||
|
||||
NodeRegisterer *bootstrap.Registerer
|
||||
}
|
||||
|
||||
const (
|
||||
// NetmapContractName is a Netmap contract's config section name.
|
||||
NetmapContractName = "netmap"
|
||||
|
||||
netmapContractAddPeerOpt = "add_peer_method"
|
||||
|
||||
netmapContractNewEpochOpt = "new_epoch_method"
|
||||
|
||||
netmapContractNetmapOpt = "netmap_method"
|
||||
|
||||
netmapContractUpdStateOpt = "update_state_method"
|
||||
|
||||
netmapContractIRListOpt = "ir_list_method"
|
||||
)
|
||||
|
||||
// NetmapContractAddPeerOptPath returns the config path to add peer method of Netmap contract.
|
||||
func NetmapContractAddPeerOptPath() string {
|
||||
return optPath(prefix, NetmapContractName, netmapContractAddPeerOpt)
|
||||
}
|
||||
|
||||
// NetmapContractNewEpochOptPath returns the config path to new epoch method of Netmap contract.
|
||||
func NetmapContractNewEpochOptPath() string {
|
||||
return optPath(prefix, NetmapContractName, netmapContractNewEpochOpt)
|
||||
}
|
||||
|
||||
// NetmapContractNetmapOptPath returns the config path to get netmap method of Netmap contract.
|
||||
func NetmapContractNetmapOptPath() string {
|
||||
return optPath(prefix, NetmapContractName, netmapContractNetmapOpt)
|
||||
}
|
||||
|
||||
// NetmapContractUpdateStateOptPath returns the config path to update state method of Netmap contract.
|
||||
func NetmapContractUpdateStateOptPath() string {
|
||||
return optPath(prefix, NetmapContractName, netmapContractUpdStateOpt)
|
||||
}
|
||||
|
||||
// NetmapContractIRListOptPath returns the config path to inner ring list method of Netmap contract.
|
||||
func NetmapContractIRListOptPath() string {
|
||||
return optPath(prefix, NetmapContractName, netmapContractIRListOpt)
|
||||
}
|
||||
|
||||
func newNetmapContract(p contractParams) (res netmapContractResult, err error) {
|
||||
client, ok := p.MorphContracts[NetmapContractName]
|
||||
if !ok {
|
||||
err = errors.Errorf("missing %s contract client", NetmapContractName)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
addPeerMethod = p.Viper.GetString(NetmapContractAddPeerOptPath())
|
||||
newEpochMethod = p.Viper.GetString(NetmapContractNewEpochOptPath())
|
||||
netmapMethod = p.Viper.GetString(NetmapContractNetmapOptPath())
|
||||
updStateMethod = p.Viper.GetString(NetmapContractUpdateStateOptPath())
|
||||
irListMethod = p.Viper.GetString(NetmapContractIRListOptPath())
|
||||
)
|
||||
|
||||
var c *contract.Client
|
||||
if c, err = contract.New(client,
|
||||
contract.WithAddPeerMethod(addPeerMethod),
|
||||
contract.WithNewEpochMethod(newEpochMethod),
|
||||
contract.WithNetMapMethod(netmapMethod),
|
||||
contract.WithUpdateStateMethod(updStateMethod),
|
||||
contract.WithInnerRingListMethod(irListMethod),
|
||||
); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if res.Client, err = clientWrapper.New(c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if res.NodeRegisterer, err = bootstrap.New(res.Client, p.NodeInfo); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue