Initial commit

Initial public review release v0.10.0
This commit is contained in:
alexvanin 2020-07-10 17:17:51 +03:00 committed by Stanislav Bogatyrev
commit dadfd90dcd
276 changed files with 46331 additions and 0 deletions

67
modules/morph/balance.go Normal file
View file

@ -0,0 +1,67 @@
package morph
import (
"github.com/nspcc-dev/neofs-node/lib/implementations"
"github.com/nspcc-dev/neofs-node/services/public/accounting"
"github.com/pkg/errors"
"go.uber.org/dig"
)
type balanceContractResult struct {
dig.Out
BalanceContract implementations.MorphBalanceContract
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
}
morphClient := implementations.MorphBalanceContract{}
morphClient.SetBalanceContractClient(client)
morphClient.SetBalanceOfMethodName(
p.Viper.GetString(
BalanceContractBalanceOfOptPath(),
),
)
morphClient.SetDecimalsMethodName(
p.Viper.GetString(
BalanceContractDecimalsOfOptPath(),
),
)
if res.AccountingService, err = accounting.New(accounting.Params{
MorphBalanceContract: morphClient,
}); err != nil {
return
}
res.BalanceContract = morphClient
return
}

140
modules/morph/common.go Normal file
View file

@ -0,0 +1,140 @@
package morph
import (
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neofs-api-go/bootstrap"
"github.com/nspcc-dev/neofs-node/lib/blockchain/event"
"github.com/nspcc-dev/neofs-node/lib/blockchain/goclient"
"github.com/nspcc-dev/neofs-node/lib/implementations"
"github.com/spf13/viper"
"go.uber.org/dig"
"go.uber.org/zap"
)
// SmartContracts maps smart contract name to contract client.
type SmartContracts map[string]implementations.StaticContractClient
// EventHandlers maps notification event name to handler information.
type EventHandlers map[string]event.HandlerInfo
type morphContractsParams struct {
dig.In
Viper *viper.Viper
GoClient *goclient.Client
Listener event.Listener
}
type contractParams struct {
dig.In
Viper *viper.Viper
Logger *zap.Logger
MorphContracts SmartContracts
NodeInfo bootstrap.NodeInfo
}
func newMorphContracts(p morphContractsParams) (SmartContracts, EventHandlers, error) {
mContracts := make(map[string]implementations.StaticContractClient, 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 = implementations.NewStaticContractClient(p.GoClient, 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,
reputationContractName,
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)
}

122
modules/morph/container.go Normal file
View file

@ -0,0 +1,122 @@
package morph
import (
"github.com/nspcc-dev/neofs-node/lib/acl"
"github.com/nspcc-dev/neofs-node/lib/container"
"github.com/nspcc-dev/neofs-node/lib/implementations"
"github.com/pkg/errors"
"go.uber.org/dig"
)
type containerContractResult struct {
dig.Out
ContainerContract *implementations.MorphContainerContract
BinaryExtendedACLStore acl.BinaryExtendedACLStore
ExtendedACLSource acl.ExtendedACLSource
ContainerStorage container.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
}
morphClient := new(implementations.MorphContainerContract)
morphClient.SetContainerContractClient(client)
morphClient.SetEACLSetMethodName(
p.Viper.GetString(
ContainerContractSetEACLOptPath(),
),
)
morphClient.SetEACLGetMethodName(
p.Viper.GetString(
ContainerContractEACLOptPath(),
),
)
morphClient.SetContainerGetMethodName(
p.Viper.GetString(
ContainerContractGetOptPath(),
),
)
morphClient.SetContainerPutMethodName(
p.Viper.GetString(
ContainerContractPutOptPath(),
),
)
morphClient.SetContainerDeleteMethodName(
p.Viper.GetString(
ContainerContractDelOptPath(),
),
)
morphClient.SetContainerListMethodName(
p.Viper.GetString(
ContainerContractListOptPath(),
),
)
res.ContainerContract = morphClient
res.BinaryExtendedACLStore = morphClient
res.ExtendedACLSource, err = implementations.ExtendedACLSourceFromBinary(res.BinaryExtendedACLStore)
if err != nil {
return
}
res.ContainerStorage = morphClient
return res, nil
}

28
modules/morph/event.go Normal file
View file

@ -0,0 +1,28 @@
package morph
import (
"github.com/nspcc-dev/neofs-node/lib/blockchain/event"
"github.com/nspcc-dev/neofs-node/lib/blockchain/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,
},
},
}

32
modules/morph/goclient.go Normal file
View file

@ -0,0 +1,32 @@
package morph
import (
"context"
"crypto/ecdsa"
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neofs-node/lib/blockchain/goclient"
"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 newMorphClient(p morphClientParams) (*goclient.Client, error) {
return goclient.New(context.Background(), &goclient.Params{
Log: p.Logger,
Key: p.Key,
Endpoint: p.Viper.GetString(optPath(prefix, endpointOpt)),
DialTimeout: p.Viper.GetDuration(optPath(prefix, dialTimeoutOpt)),
Magic: netmode.Magic(p.Viper.GetUint32(optPath(prefix, magicNumberOpt))),
})
}

53
modules/morph/listener.go Normal file
View file

@ -0,0 +1,53 @@
package morph
import (
"context"
"github.com/nspcc-dev/neofs-node/lib/blockchain/event"
"github.com/nspcc-dev/neofs-node/lib/blockchain/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,
})
}

22
modules/morph/module.go Normal file
View file

@ -0,0 +1,22 @@
package morph
import (
"strings"
"github.com/nspcc-dev/neofs-node/lib/fix/module"
)
// Module is a Neo:Morph module.
var Module = module.Module{
{Constructor: newMorphClient},
{Constructor: newMorphContracts},
{Constructor: newContainerContract},
{Constructor: newReputationContract},
{Constructor: newNetmapContract},
{Constructor: newEventListener},
{Constructor: newBalanceContract},
}
func optPath(sections ...string) string {
return strings.Join(sections, ".")
}

115
modules/morph/netmap.go Normal file
View file

@ -0,0 +1,115 @@
package morph
import (
"github.com/nspcc-dev/neofs-node/lib/boot"
"github.com/nspcc-dev/neofs-node/lib/implementations"
"github.com/nspcc-dev/neofs-node/lib/ir"
"github.com/nspcc-dev/neofs-node/lib/netmap"
"github.com/pkg/errors"
"go.uber.org/dig"
)
type netmapContractResult struct {
dig.Out
NetmapContract *implementations.MorphNetmapContract
NetMapStorage netmap.Storage
IRStorage ir.Storage
StorageBootController boot.StorageBootController
}
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
}
morphClient := new(implementations.MorphNetmapContract)
morphClient.SetNetmapContractClient(client)
morphClient.SetAddPeerMethodName(
p.Viper.GetString(
NetmapContractAddPeerOptPath(),
),
)
morphClient.SetNewEpochMethodName(
p.Viper.GetString(
NetmapContractNewEpochOptPath(),
),
)
morphClient.SetNetMapMethodName(
p.Viper.GetString(
NetmapContractNetmapOptPath(),
),
)
morphClient.SetUpdateStateMethodName(
p.Viper.GetString(
NetmapContractUpdateStateOptPath(),
),
)
morphClient.SetIRListMethodName(
p.Viper.GetString(
NetmapContractIRListOptPath(),
),
)
bootCtrl := boot.StorageBootController{}
bootCtrl.SetPeerBootstrapper(morphClient)
bootCtrl.SetLogger(p.Logger)
bootPrm := boot.StorageBootParams{}
bootPrm.SetNodeInfo(&p.NodeInfo)
bootCtrl.SetBootParams(bootPrm)
res.StorageBootController = bootCtrl
res.NetmapContract = morphClient
res.NetMapStorage = morphClient
res.IRStorage = morphClient
return res, nil
}

View file

@ -0,0 +1,59 @@
package morph
import (
"github.com/nspcc-dev/neofs-node/lib/implementations"
"github.com/nspcc-dev/neofs-node/lib/peers"
"github.com/pkg/errors"
"go.uber.org/dig"
)
type reputationContractResult struct {
dig.Out
ReputationContract implementations.MorphReputationContract
}
const (
reputationContractName = "reputation"
reputationContractPutOpt = "put_method"
reputationContractListOpt = "list_method"
)
// ReputationContractPutOptPath returns the config path to put method of Reputation contract.
func ReputationContractPutOptPath() string {
return optPath(prefix, reputationContractName, reputationContractPutOpt)
}
// ReputationContractListOptPath returns the config path to list method of Reputation contract.
func ReputationContractListOptPath() string {
return optPath(prefix, reputationContractName, reputationContractListOpt)
}
func newReputationContract(p contractParams, ps peers.Store) (res reputationContractResult, err error) {
cli, ok := p.MorphContracts[reputationContractName]
if !ok {
err = errors.Errorf("missing %s contract client", reputationContractName)
return
}
morphClient := implementations.MorphReputationContract{}
morphClient.SetReputationContractClient(cli)
morphClient.SetPublicKeyStore(ps)
morphClient.SetPutMethodName(
p.Viper.GetString(
ReputationContractPutOptPath(),
),
)
morphClient.SetListMethodName(
p.Viper.GetString(
ReputationContractListOptPath(),
),
)
res.ReputationContract = morphClient
return
}