Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cosmos integration #1211

Merged
merged 9 commits into from
Aug 13, 2019
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ mesg-dev
bin/cli
docs/
docker-images/
.tendermint-validator/
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ node_modules
# do not store vendor dir
vendor
tmp-systemservices

# tendermint
.tendermint-validator/
42 changes: 39 additions & 3 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"encoding/hex"
"fmt"
"os"
"path/filepath"
Expand All @@ -10,6 +11,7 @@ import (
"github.com/mesg-foundation/engine/x/xstrings"
homedir "github.com/mitchellh/go-homedir"
"github.com/sirupsen/logrus"
"github.com/tendermint/tendermint/crypto/ed25519"
)

const (
Expand Down Expand Up @@ -48,6 +50,15 @@ type Config struct {
WorkflowRelativePath string
}

Tendermint struct {
Path string
ValidatorPubKey PubKeyEd25519
P2P struct {
Seeds string
ExternalAddress string
}
}

SystemServices []*ServiceConfig
}

Expand All @@ -69,6 +80,7 @@ func New() (*Config, error) {
c.Database.InstanceRelativePath = filepath.Join("database", "instance", instanceDBVersion)
c.Database.ExecutionRelativePath = filepath.Join("database", "executions", executionDBVersion)
c.Database.WorkflowRelativePath = filepath.Join("database", "workflows", workflowDBVersion)
c.Tendermint.Path = "tendermint"
return &c, c.setupServices()
}

Expand Down Expand Up @@ -98,13 +110,15 @@ func Global() (*Config, error) {

// Load reads config from environmental variables.
func (c *Config) Load() error {
envconfig.MustProcess(envPrefix, c)
return nil
return envconfig.Process(envPrefix, c)
}

// Prepare setups local directories or any other required thing based on config
func (c *Config) Prepare() error {
return os.MkdirAll(c.Path, os.FileMode(0755))
if err := os.MkdirAll(c.Path, os.FileMode(0755)); err != nil {
return err
}
return os.MkdirAll(filepath.Join(c.Path, c.Tendermint.Path), os.FileMode(0755))
}

// Validate checks values and return an error if any validation failed.
Expand All @@ -117,3 +131,25 @@ func (c *Config) Validate() error {
}
return nil
}

// PubKeyEd25519 is type used to parse value provided by envconfig.
type PubKeyEd25519 ed25519.PubKeyEd25519

// Decode parses string value as hex ed25519 key.
func (key *PubKeyEd25519) Decode(value string) error {
if value == "" {
return fmt.Errorf("validator public key is empty")
}

dec, err := hex.DecodeString(value)
if err != nil {
return fmt.Errorf("validator public key decode error: %s", err)
}

if len(dec) != ed25519.PubKeyEd25519Size {
return fmt.Errorf("validator public key %s has invalid size", value)
}

copy(key[:], dec)
return nil
}
70 changes: 48 additions & 22 deletions core/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,67 +15,65 @@ import (
instancesdk "github.com/mesg-foundation/engine/sdk/instance"
servicesdk "github.com/mesg-foundation/engine/sdk/service"
"github.com/mesg-foundation/engine/server/grpc"
"github.com/mesg-foundation/engine/tendermint"
"github.com/mesg-foundation/engine/tendermint/app"
"github.com/mesg-foundation/engine/version"
"github.com/mesg-foundation/engine/x/xerrors"
"github.com/mesg-foundation/engine/x/xnet"
"github.com/mesg-foundation/engine/x/xos"
"github.com/mesg-foundation/engine/x/xsignal"
"github.com/sirupsen/logrus"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/libs/db"
)

type dependencies struct {
config *config.Config
cfg *config.Config
serviceDB database.ServiceDB
executionDB database.ExecutionDB
workflowDB database.WorkflowDB
container container.Container
sdk *sdk.SDK
}

func initDependencies() (*dependencies, error) {
// init configs.
config, err := config.Global()
if err != nil {
return nil, err
}

func initDependencies(cfg *config.Config) (*dependencies, error) {
// init services db.
serviceDB, err := database.NewServiceDB(filepath.Join(config.Path, config.Database.ServiceRelativePath))
serviceDB, err := database.NewServiceDB(filepath.Join(cfg.Path, cfg.Database.ServiceRelativePath))
if err != nil {
return nil, err
}

// init instance db.
instanceDB, err := database.NewInstanceDB(filepath.Join(config.Path, config.Database.InstanceRelativePath))
instanceDB, err := database.NewInstanceDB(filepath.Join(cfg.Path, cfg.Database.InstanceRelativePath))
if err != nil {
return nil, err
}

// init execution db.
executionDB, err := database.NewExecutionDB(filepath.Join(config.Path, config.Database.ExecutionRelativePath))
executionDB, err := database.NewExecutionDB(filepath.Join(cfg.Path, cfg.Database.ExecutionRelativePath))
if err != nil {
return nil, err
}

// init workflow db.
workflowDB, err := database.NewWorkflowDB(filepath.Join(config.Path, config.Database.WorkflowRelativePath))
workflowDB, err := database.NewWorkflowDB(filepath.Join(cfg.Path, cfg.Database.WorkflowRelativePath))
if err != nil {
return nil, err
}

// init container.
c, err := container.New(config.Name)
c, err := container.New(cfg.Name)
if err != nil {
return nil, err
}

_, port, _ := xnet.SplitHostPort(config.Server.Address)
_, port, _ := xnet.SplitHostPort(cfg.Server.Address)

// init sdk.
sdk := sdk.New(c, serviceDB, instanceDB, executionDB, workflowDB, config.Name, strconv.Itoa(port))
sdk := sdk.New(c, serviceDB, instanceDB, executionDB, workflowDB, cfg.Name, strconv.Itoa(port))

return &dependencies{
config: config,
cfg: cfg,
container: c,
serviceDB: serviceDB,
executionDB: executionDB,
Expand All @@ -84,8 +82,8 @@ func initDependencies() (*dependencies, error) {
}, nil
}

func deployCoreServices(config *config.Config, sdk *sdk.SDK) error {
for _, serviceConfig := range config.SystemServices {
func deployCoreServices(cfg *config.Config, sdk *sdk.SDK) error {
for _, serviceConfig := range cfg.SystemServices {
logrus.WithField("module", "main").Infof("Deploying service %q", serviceConfig.Definition.Sid)
srv, err := sdk.Service.Create(serviceConfig.Definition)
if err != nil {
Expand Down Expand Up @@ -148,16 +146,39 @@ func stopRunningServices(sdk *sdk.SDK) error {
}

func main() {
dep, err := initDependencies()
cfg, err := config.Global()
if err != nil {
logrus.Fatalln(err)
}

dep, err := initDependencies(cfg)
if err != nil {
logrus.WithField("module", "main").Fatalln(err)
}

// init logger.
logger.Init(dep.config.Log.Format, dep.config.Log.Level, dep.config.Log.ForceColors)
logger.Init(cfg.Log.Format, cfg.Log.Level, cfg.Log.ForceColors)

// init app
db := db.NewMemDB()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't matter for this PR but just a reminder that this is in memory

logger := logger.TendermintLogger()
app := app.New(logger, db)

// create tendermint node
node, err := tendermint.NewNode(
logger,
app,
filepath.Join(cfg.Path, cfg.Tendermint.Path),
cfg.Tendermint.P2P.Seeds,
cfg.Tendermint.P2P.ExternalAddress,
ed25519.PubKeyEd25519(cfg.Tendermint.ValidatorPubKey),
)
if err != nil {
logrus.Fatalln(err)
}

// init system services.
if err := deployCoreServices(dep.config, dep.sdk); err != nil {
if err := deployCoreServices(dep.cfg, dep.sdk); err != nil {
logrus.WithField("module", "main").Fatalln(err)
}

Expand All @@ -167,11 +188,16 @@ func main() {
logrus.WithField("module", "main").Infof("starting MESG Engine version %s", version.Version)

go func() {
if err := server.Serve(dep.config.Server.Address); err != nil {
if err := server.Serve(cfg.Server.Address); err != nil {
logrus.WithField("module", "main").Fatalln(err)
}
}()

logrus.WithField("module", "main").WithField("seeds", cfg.Tendermint.P2P.Seeds).Info("starting tendermint node")
if err := node.Start(); err != nil {
logrus.Fatalln(err)
}

logrus.WithField("module", "main").Info("starting workflow engine")
s := scheduler.New(dep.sdk.Event, dep.sdk.Execution, dep.sdk.Workflow)
go func() {
Expand Down
39 changes: 37 additions & 2 deletions dev
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,51 @@ set -e

DIR=$(pwd)

# network to connect multiple engine instances
TENDERMINT_NETWORK="mesg-tendermint"

# mesg config variables
MESG_NAME=${MESG_NAME:-engine}
MESG_PATH=${MESG_PATH:-$HOME/.mesg}
MESG_LOG_FORMAT=${MESG_LOG_FORMAT:-text}
MESG_LOG_FORCECOLORS=${MESG_LOG_FORCECOLORS:-false}
MESG_LOG_LEVEL=${MESG_LOG_LEVEL:-debug}
MESG_SERVER_PORT=${MESG_SERVER_PORT:-50052}
MESG_TENDERMINT_PATH=${MESG_TENDERMINT_PATH:-"tendermint"}

TENDERMINT_NETWORK_ALIAS=${TENDERMINT_NETWORK_ALIAS:-$MESG_NAME}
TENDERMINT_VALIDATOR_NAME=${TENDERMINT_VALIDATOR_NAME:-validator}
TENDERMINT_VALIDATOR_PORT=${TENDERMINT_VALIDATOR_PORT:-26656}
TENDERMINT_VALIDATOR_PATH=${TENDERMINT_VALIDATOR_PATH:-".tendermint-validator"}

# Init and read validator identity
eval $(go run internal/tools/gen_tm_identity.go -name=$TENDERMINT_VALIDATOR_NAME -port=$TENDERMINT_VALIDATOR_PORT -path=$TENDERMINT_VALIDATOR_PATH)
MESG_TENDERMINT_P2P_SEEDS=${MESG_TENDERMINT_P2P_SEEDS:-$NODE_PUBKEY}
MESG_TENDERMINT_VALIDATORPUBKEY=${MESG_TENDERMINT_VALIDATORPUBKEY:-$VALIDATOR_PUBKEY}

# Setup the validator private keys
if [[ $* == *--validator* ]]; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@krhubert if you know a better way to read flag but definitely not blocking

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, there is getopts tool (one of many examples https://sookocheff.com/post/bash/parsing-bash-script-arguments-with-shopts/)

TENDERMINT_HOME_CONFIG=$MESG_PATH/$MESG_TENDERMINT_PATH
echo "Validator flag passed. Copy validator private keys to $TENDERMINT_HOME_CONFIG"
mkdir -p $TENDERMINT_HOME_CONFIG
cp -R $TENDERMINT_VALIDATOR_PATH/ $TENDERMINT_HOME_CONFIG
TENDERMINT_NETWORK_ALIAS=$TENDERMINT_VALIDATOR_NAME
TENDERMINT_VALIDATOR_PORT_PUBLISH="--publish $TENDERMINT_VALIDATOR_PORT:$TENDERMINT_VALIDATOR_PORT"
fi

VERSION=local
LDFLAGS="-X 'github.com/mesg-foundation/engine/version.Version=$VERSION'"
LDFLAGS+=" -X 'github.com/mesg-foundation/engine/config.EnvMarketplaceEndpoint=https://ropsten.infura.io/v3/6115ae2531f64c04a9a392cf500e5fbe'"
LDFLAGS+=" -X 'github.com/mesg-foundation/engine/config.EnvMarketplaceAddress=0xeCC1A867F871323350A1A89FcAf69629a2d5085e'"
LDFLAGS+=" -X 'github.com/mesg-foundation/engine/config.EnvMarketplaceToken=0x5861b3dc52339d4f976b7fa5d80db6cd6f477f1b'"

MESG_SERVER_PORT=${MESG_SERVER_PORT:-50052}

function onexit {
set +e
echo -e "\nshuting down, please wait..."
echo -e "\nshutting down, please wait..."
docker_service_remove "$MESG_NAME"
docker_network_remove "$MESG_NAME"
docker_network_remove "$TENDERMINT_NETWORK"
}

function docker_service_remove {
Expand Down Expand Up @@ -96,6 +121,10 @@ if ! docker_network_exist "$MESG_NAME"; then
docker_network_create "$MESG_NAME"
fi

if ! docker_network_exist "$TENDERMINT_NETWORK"; then
docker_network_create "$TENDERMINT_NETWORK"
fi

echo "create docker service: "
docker service create \
--name $MESG_NAME \
Expand All @@ -106,10 +135,16 @@ docker service create \
--env MESG_LOG_FORMAT=$MESG_LOG_FORMAT \
--env MESG_LOG_FORCECOLORS=$MESG_LOG_FORCECOLORS \
--env MESG_LOG_LEVEL=$MESG_LOG_LEVEL \
--env MESG_TENDERMINT_PATH=$MESG_TENDERMINT_PATH \
--env MESG_TENDERMINT_VALIDATORPUBKEY=$MESG_TENDERMINT_VALIDATORPUBKEY \
--env MESG_TENDERMINT_P2P_SEEDS=$MESG_TENDERMINT_P2P_SEEDS \
--env MESG_TENDERMINT_P2P_EXTERNALADDRESS=$MESG_TENDERMINT_P2P_EXTERNALADDRESS \
--mount type=bind,source=/var/run/docker.sock,destination=/var/run/docker.sock \
--mount type=bind,source=$MESG_PATH,destination=/root/.mesg \
--network $MESG_NAME \
--network name=$TENDERMINT_NETWORK,alias=$TENDERMINT_NETWORK_ALIAS \
--publish $MESG_SERVER_PORT:50052 \
$TENDERMINT_VALIDATOR_PORT_PUBLISH \
mesg/engine:$VERSION

docker service logs --follow --raw $MESG_NAME
Loading