From 5ec7b71d92ea69c8963aa89dd6ce5cf18942c43c Mon Sep 17 00:00:00 2001 From: Wondertan Date: Wed, 29 Sep 2021 23:49:08 +0300 Subject: [PATCH 01/15] feat(node): add Node Type parsing from string --- cmd/celestia/full.go | 17 +++++++++++++++++ cmd/celestia/light.go | 17 +++++++++++++++++ cmd/celestia/main.go | 38 ++++++++++++++++++++++++++++++++++++++ cmd/init.go | 1 + node/type.go | 16 ++++++++++++++++ 5 files changed, 89 insertions(+) create mode 100644 cmd/celestia/full.go create mode 100644 cmd/celestia/light.go create mode 100644 cmd/celestia/main.go create mode 100644 cmd/init.go diff --git a/cmd/celestia/full.go b/cmd/celestia/full.go new file mode 100644 index 0000000000..9abd4a5388 --- /dev/null +++ b/cmd/celestia/full.go @@ -0,0 +1,17 @@ +package main + +import ( + "github.com/spf13/cobra" + + "github.com/celestiaorg/celestia-node/node" +) + +func init() { + fullCmd.AddCommand(initCmd) + fullCmd.Annotations[tp] = node.Full.String() + fullCmd.PersistentFlags().StringP("repository", "r", "~/.celestia-full", "The root/home directory for your Celestial Full Node") +} + +var fullCmd = &cobra.Command{ + Use: "full [subcommand]", +} \ No newline at end of file diff --git a/cmd/celestia/light.go b/cmd/celestia/light.go new file mode 100644 index 0000000000..e4ef8920b6 --- /dev/null +++ b/cmd/celestia/light.go @@ -0,0 +1,17 @@ +package main + +import ( + "github.com/spf13/cobra" + + "github.com/celestiaorg/celestia-node/node" +) + +func init() { + lightCmd.AddCommand(lightCmd) + lightCmd.Annotations[tp] = node.Light.String() + lightCmd.PersistentFlags().String("repository", "~/.celestia-light", "The root/home directory for your Celestial Light Node") +} + +var lightCmd = &cobra.Command{ + Use: "light [subcommand]", +} diff --git a/cmd/celestia/main.go b/cmd/celestia/main.go new file mode 100644 index 0000000000..5f9927a3cb --- /dev/null +++ b/cmd/celestia/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "github.com/spf13/cobra" + + "github.com/celestiaorg/celestia-node/node" +) + +func init() { + rootCmd.AddCommand(fullCmd) + rootCmd.AddCommand(lightCmd) +} + +func main() { + err := run() + if err != nil { + return + } +} + +func run() error { + return rootCmd.Execute() +} + +var rootCmd = &cobra.Command{ + Use: "celestia [subcommand]", +} + +const tp = "type" + +var initCmd = &cobra.Command{ + RunE: func(cmd *cobra.Command, args []string) error { + tp := node.ParseType(cmd.Annotations["type"]) + path := cmd.Flag("repository").Value.String() + node.Init(path, ) + }, +} + diff --git a/cmd/init.go b/cmd/init.go new file mode 100644 index 0000000000..1d619dd05e --- /dev/null +++ b/cmd/init.go @@ -0,0 +1 @@ +package cmd diff --git a/node/type.go b/node/type.go index 0032edcd47..fad9f22f89 100644 --- a/node/type.go +++ b/node/type.go @@ -26,8 +26,24 @@ func (t Type) IsValid() bool { return ok } +// ParseType converts string in a type if possible. +func ParseType(str string) Type { + tp, ok := stringToType[str] + if !ok { + return 0 + } + + return tp +} + // typeToString keeps string representations of all valid Types. var typeToString = map[Type]string{ Full: "Full", Light: "Light", } + +// typeToString maps strings representations of all valid Types. +var stringToType = map[string]Type{ + "Full": Full, + "Light": Light, +} \ No newline at end of file From b686db14b4d580e86be1b56ff7621b553c0db92f Mon Sep 17 00:00:00 2001 From: Wondertan Date: Wed, 29 Sep 2021 23:51:35 +0300 Subject: [PATCH 02/15] feat(node): new InitWith to allow custom configs --- node/init.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/node/init.go b/node/init.go index 0c94be5c09..6d50b62f01 100644 --- a/node/init.go +++ b/node/init.go @@ -9,9 +9,15 @@ import ( "github.com/celestiaorg/celestia-node/libs/utils" ) -// Init initializes the Node FileSystem(FS) Repository for th given Node Type 'tp' in the directory under 'path' with -// the given Config. +// Init initializes the Node FileSystem Repository for the given Node Type 'tp' in the directory under 'path' with +// default Config. func Init(path string, tp Type) error { + return InitWith(path, tp, DefaultConfig(tp)) +} + +// InitWith initializes the Node FileSystem Repository for the given Node Type 'tp' in the directory under 'path' +// with the given Config 'cfg'. +func InitWith(path string, tp Type, cfg *Config) error { path, err := repoPath(path) if err != nil { return err @@ -71,7 +77,7 @@ func Init(path string, tp Type) error { return nil } -// IsInit checks whether FS Repository was setup under given 'path'. +// IsInit checks whether FileSystem Repository was setup under given 'path'. // If any required file/subdirectory does not exist, then false is reported. func IsInit(path string, tp Type) bool { path, err := repoPath(path) From 90397e86ded1556e7c90d435463c72ed53af34b4 Mon Sep 17 00:00:00 2001 From: Wondertan Date: Wed, 29 Sep 2021 23:53:27 +0300 Subject: [PATCH 03/15] fix(node): ensure root is created before locking and improve logging --- core/init.go | 4 ++-- node/init.go | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/core/init.go b/core/init.go index c1e4947a92..6c161c4501 100644 --- a/core/init.go +++ b/core/init.go @@ -24,8 +24,8 @@ const defaultValKeyType = types.ABCIPubKeyTypeSecp256k1 // * P2P comms private key // * Stub genesis doc file func Init(path string) (err error) { - log.Info("Initializing Repository over '%s'", path) - defer log.Info("Repository initialized") + log.Infof("Initializing Core Repository over '%s'", path) + defer log.Info("Core Repository initialized") // 1 - ensure config cfg := DefaultConfig() diff --git a/node/init.go b/node/init.go index 6d50b62f01..0ebbc71494 100644 --- a/node/init.go +++ b/node/init.go @@ -22,8 +22,13 @@ func InitWith(path string, tp Type, cfg *Config) error { if err != nil { return err } - log.Info("Initializing Repository for the Node over '%s'", path) - defer log.Info("Repository initialized") + log.Infof("Initializing %s Node Repository over '%s'", tp, path) + defer log.Info("Node Repository initialized") + + err = initRoot(path) + if err != nil { + return err + } flock, err := fslock.Lock(lockPath(path)) if err != nil { @@ -34,11 +39,6 @@ func InitWith(path string, tp Type, cfg *Config) error { } defer flock.Unlock() //nolint: errcheck - err = initRoot(path) - if err != nil { - return err - } - err = initDir(keysPath(path)) if err != nil { return err @@ -49,14 +49,13 @@ func InitWith(path string, tp Type, cfg *Config) error { return err } - cfg := DefaultConfig(tp) cfgPath := configPath(path) if !utils.Exists(cfgPath) { err = SaveConfig(cfgPath, cfg) if err != nil { return err } - log.Info("New config is generated") + log.Info("Saving config") } else { log.Info("Config already exists") } From dd08680ca6a0b430fec53cc8116ca1141d75f22d Mon Sep 17 00:00:00 2001 From: Wondertan Date: Wed, 29 Sep 2021 23:56:23 +0300 Subject: [PATCH 04/15] feat(cmd): start implementing CLI with Init command ing cmd packge using 'cobra' --- cmd/init.go | 39 +++++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 3 +++ 3 files changed, 43 insertions(+) diff --git a/cmd/init.go b/cmd/init.go index 1d619dd05e..638cd4207a 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -1 +1,40 @@ package cmd + +import ( + "github.com/spf13/cobra" + + "github.com/celestiaorg/celestia-node/node" +) + +// Init constructs a CLI command to initialize Celestia Node of the given type 'tp'. +// It is meant to be used a subcommand and also receive persistent flag name for repository path. +func Init(repoName string, tp node.Type) *cobra.Command { + if !tp.IsValid() { + panic("Init: invalid Node Type") + } + if len(repoName) == 0 { + panic("parent command must specify a persistent flag name for repository path") + } + + const cfgName = "config" + cmd := &cobra.Command{ + Use: "init [subcommand]", + RunE: func(cmd *cobra.Command, args []string) error { + cfgF := cmd.Flag(cfgName).Value + repo := cmd.Flag(repoName).Value.String() + + if len(cfgF.String()) != 0 { + cfg, err := node.LoadConfig(cfgF.String()) + if err != nil { + return err + } + + return node.InitWith(repo, tp, cfg) + } + + return node.Init(repo, tp) + }, + } + cmd.Flags().StringP(cfgName, "c", "", "Path to a customized Config") + return cmd +} diff --git a/go.mod b/go.mod index c4239ed3d7..0d25e8615b 100644 --- a/go.mod +++ b/go.mod @@ -34,6 +34,7 @@ require ( github.com/multiformats/go-base32 v0.0.4 github.com/multiformats/go-multiaddr v0.4.0 github.com/multiformats/go-multihash v0.0.15 + github.com/spf13/cobra v1.2.1 github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 go.uber.org/fx v1.14.2 go.uber.org/zap v1.19.0 diff --git a/go.sum b/go.sum index 945b5fa149..eb96ad7f8d 100644 --- a/go.sum +++ b/go.sum @@ -415,6 +415,7 @@ github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSa github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= @@ -1156,12 +1157,14 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cobra v0.0.0-20170417170307-b6cb39589372/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170417173400-9e4c21054fa1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= From 308a05c9bd22e8558bb07ce46bee85da806e8c77 Mon Sep 17 00:00:00 2001 From: Wondertan Date: Wed, 29 Sep 2021 23:57:08 +0300 Subject: [PATCH 05/15] feat(cmd/celestia): main function with full and light commands --- cmd/celestia/full.go | 11 ++++++++--- cmd/celestia/light.go | 12 +++++++++--- cmd/celestia/main.go | 18 +++--------------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/cmd/celestia/full.go b/cmd/celestia/full.go index 9abd4a5388..643d1a4334 100644 --- a/cmd/celestia/full.go +++ b/cmd/celestia/full.go @@ -3,13 +3,18 @@ package main import ( "github.com/spf13/cobra" + "github.com/celestiaorg/celestia-node/cmd" "github.com/celestiaorg/celestia-node/node" ) func init() { - fullCmd.AddCommand(initCmd) - fullCmd.Annotations[tp] = node.Full.String() - fullCmd.PersistentFlags().StringP("repository", "r", "~/.celestia-full", "The root/home directory for your Celestial Full Node") + const repoName = "repository" + fullCmd.AddCommand(cmd.Init(repoName, node.Full)) + fullCmd.PersistentFlags().StringP(repoName, + "r", + "~/.celestia-full", + "The root/home directory of your Celestial Full Node", + ) } var fullCmd = &cobra.Command{ diff --git a/cmd/celestia/light.go b/cmd/celestia/light.go index e4ef8920b6..fb401f02c4 100644 --- a/cmd/celestia/light.go +++ b/cmd/celestia/light.go @@ -3,13 +3,19 @@ package main import ( "github.com/spf13/cobra" + "github.com/celestiaorg/celestia-node/cmd" "github.com/celestiaorg/celestia-node/node" ) func init() { - lightCmd.AddCommand(lightCmd) - lightCmd.Annotations[tp] = node.Light.String() - lightCmd.PersistentFlags().String("repository", "~/.celestia-light", "The root/home directory for your Celestial Light Node") + const repoName = "repository" + lightCmd.AddCommand(cmd.Init(repoName, node.Light)) + lightCmd.PersistentFlags().StringP( + repoName, + "r", + "~/.celestia-light", + "The root/home directory of your Celestial Light Node", + ) } var lightCmd = &cobra.Command{ diff --git a/cmd/celestia/main.go b/cmd/celestia/main.go index 5f9927a3cb..80eac5b227 100644 --- a/cmd/celestia/main.go +++ b/cmd/celestia/main.go @@ -1,14 +1,12 @@ package main import ( + logging "github.com/ipfs/go-log/v2" "github.com/spf13/cobra" - - "github.com/celestiaorg/celestia-node/node" ) func init() { - rootCmd.AddCommand(fullCmd) - rootCmd.AddCommand(lightCmd) + rootCmd.AddCommand(fullCmd, lightCmd) } func main() { @@ -19,20 +17,10 @@ func main() { } func run() error { + logging.SetAllLoggers(logging.LevelInfo) return rootCmd.Execute() } var rootCmd = &cobra.Command{ Use: "celestia [subcommand]", } - -const tp = "type" - -var initCmd = &cobra.Command{ - RunE: func(cmd *cobra.Command, args []string) error { - tp := node.ParseType(cmd.Annotations["type"]) - path := cmd.Flag("repository").Value.String() - node.Init(path, ) - }, -} - From af554fc804fc103273f731dd3667f8e0515ec605 Mon Sep 17 00:00:00 2001 From: Wondertan Date: Thu, 30 Sep 2021 00:36:04 +0300 Subject: [PATCH 06/15] cmd: multiple improvements and ASCI art --- cmd/celestia/full.go | 1 + cmd/celestia/light.go | 1 + cmd/celestia/main.go | 7 +++++++ cmd/init.go | 3 ++- 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/cmd/celestia/full.go b/cmd/celestia/full.go index 643d1a4334..5d5439a9f7 100644 --- a/cmd/celestia/full.go +++ b/cmd/celestia/full.go @@ -19,4 +19,5 @@ func init() { var fullCmd = &cobra.Command{ Use: "full [subcommand]", + Args: cobra.NoArgs, } \ No newline at end of file diff --git a/cmd/celestia/light.go b/cmd/celestia/light.go index fb401f02c4..db2f43ac13 100644 --- a/cmd/celestia/light.go +++ b/cmd/celestia/light.go @@ -20,4 +20,5 @@ func init() { var lightCmd = &cobra.Command{ Use: "light [subcommand]", + Args: cobra.NoArgs, } diff --git a/cmd/celestia/main.go b/cmd/celestia/main.go index 80eac5b227..056ceb59c9 100644 --- a/cmd/celestia/main.go +++ b/cmd/celestia/main.go @@ -23,4 +23,11 @@ func run() error { var rootCmd = &cobra.Command{ Use: "celestia [subcommand]", + Short: ` + / ____/__ / /__ _____/ /_(_)___ _ + / / / _ \/ / _ \/ ___/ __/ / __ / + / /___/ __/ / __(__ ) /_/ / /_/ / + \____/\___/_/\___/____/\__/_/\__,_/ + `, + Args: cobra.NoArgs, } diff --git a/cmd/init.go b/cmd/init.go index 638cd4207a..c7942c551f 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -18,7 +18,8 @@ func Init(repoName string, tp node.Type) *cobra.Command { const cfgName = "config" cmd := &cobra.Command{ - Use: "init [subcommand]", + Use: "init", + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { cfgF := cmd.Flag(cfgName).Value repo := cmd.Flag(repoName).Value.String() From 85be259a91f8fcd845a4ea89b040868f651273c4 Mon Sep 17 00:00:00 2001 From: Wondertan Date: Thu, 30 Sep 2021 00:37:44 +0300 Subject: [PATCH 07/15] cmd: write error to stdout --- cmd/celestia/main.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/celestia/main.go b/cmd/celestia/main.go index 056ceb59c9..40a9160ebc 100644 --- a/cmd/celestia/main.go +++ b/cmd/celestia/main.go @@ -1,6 +1,9 @@ package main import ( + "fmt" + "os" + logging "github.com/ipfs/go-log/v2" "github.com/spf13/cobra" ) @@ -12,7 +15,8 @@ func init() { func main() { err := run() if err != nil { - return + fmt.Fprintln(os.Stderr, err) + os.Exit(1) } } From 476ea14dc63f93d18457326fa39ceaaef30c11a5 Mon Sep 17 00:00:00 2001 From: Wondertan Date: Thu, 30 Sep 2021 19:36:54 +0300 Subject: [PATCH 08/15] fix(core): make core run kvapp by default --- core/config.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/config.go b/core/config.go index d6e1ecec76..219ba02a61 100644 --- a/core/config.go +++ b/core/config.go @@ -15,6 +15,8 @@ type Config = config.Config // DefaultConfig returns a modified default config of Core node. func DefaultConfig() *Config { cfg := config.DefaultConfig() + // TODO(@Wondertan): Instead, we should have celestia-app here or even allow customizing it + cfg.ProxyApp = "kvstore" updateDefaults(cfg) return cfg } From da77456d90579e33199cbbcca00644011e1230ad Mon Sep 17 00:00:00 2001 From: Wondertan Date: Thu, 30 Sep 2021 19:37:38 +0300 Subject: [PATCH 09/15] fix(node): fs repo should load and save config over config path and test for the case --- node/repo.go | 4 ++-- node/repo_test.go | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/node/repo.go b/node/repo.go index 5cfbb6c21f..327527f5cd 100644 --- a/node/repo.go +++ b/node/repo.go @@ -82,7 +82,7 @@ func (f *fsRepository) Path() string { } func (f *fsRepository) Config() (*Config, error) { - cfg, err := LoadConfig(f.path) + cfg, err := LoadConfig(configPath(f.path)) if err != nil { return nil, fmt.Errorf("node: can't load Config: %w", err) } @@ -91,7 +91,7 @@ func (f *fsRepository) Config() (*Config, error) { } func (f *fsRepository) PutConfig(cfg *Config) error { - err := SaveConfig(f.path, cfg) + err := SaveConfig(configPath(f.path), cfg) if err != nil { return fmt.Errorf("node: can't save Config: %w", err) } diff --git a/node/repo_test.go b/node/repo_test.go index c247e4fd76..86f296b71b 100644 --- a/node/repo_test.go +++ b/node/repo_test.go @@ -33,6 +33,10 @@ func TestRepoFull(t *testing.T) { crepo, err := repo.Core() assert.NoError(t, err) assert.NotNil(t, crepo) + + cfg, err := repo.Config() + assert.NoError(t, err) + assert.NotNil(t, cfg) } func TestRepoLight(t *testing.T) { @@ -61,4 +65,8 @@ func TestRepoLight(t *testing.T) { crepo, err := repo.Core() assert.Error(t, err) assert.Nil(t, crepo) + + cfg, err := repo.Config() + assert.NoError(t, err) + assert.NotNil(t, cfg) } From 9173724ade4cda4b024db93918deeff67c4b1259 Mon Sep 17 00:00:00 2001 From: Wondertan Date: Thu, 30 Sep 2021 19:40:11 +0300 Subject: [PATCH 10/15] fix(node): fix bug where Full Node was a light Node --- node/light.go | 3 --- node/node.go | 9 ++++++--- node/type.go | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/node/light.go b/node/light.go index 2440f4f494..03bb107d3e 100644 --- a/node/light.go +++ b/node/light.go @@ -13,9 +13,6 @@ func lightComponents(cfg *Config, repo Repository) fx.Option { return fx.Options( // manual providing fx.Provide(context.Background), - fx.Provide(func() Type { - return Light - }), fx.Provide(func() *Config { return cfg }), diff --git a/node/node.go b/node/node.go index 5feee3aa29..e680af185a 100644 --- a/node/node.go +++ b/node/node.go @@ -58,9 +58,9 @@ func New(tp Type, repo Repository) (*Node, error) { switch tp { case Full: - return newNode(fullComponents(cfg, repo)) + return newNode(tp, fullComponents(cfg, repo)) case Light: - return newNode(lightComponents(cfg, repo)) + return newNode(tp, lightComponents(cfg, repo)) default: panic("node: unknown Node Type") } @@ -122,12 +122,15 @@ func (n *Node) Stop(ctx context.Context) error { // DI options allow initializing the Node with a customized set of components and services. // NOTE: newNode is currently meant to be used privately to create various custom Node types e.g. full, unless we // decide to give package users the ability to create custom node types themselves. -func newNode(opts ...fx.Option) (*Node, error) { +func newNode(tp Type, opts ...fx.Option) (*Node, error) { node := new(Node) node.app = fx.New( fx.NopLogger, fx.Extract(node), fx.Options(opts...), + fx.Provide(func() Type { + return tp + }), ) return node, node.app.Err() } diff --git a/node/type.go b/node/type.go index fad9f22f89..58469bb991 100644 --- a/node/type.go +++ b/node/type.go @@ -44,6 +44,6 @@ var typeToString = map[Type]string{ // typeToString maps strings representations of all valid Types. var stringToType = map[string]Type{ - "Full": Full, + "Full": Full, "Light": Light, -} \ No newline at end of file +} From e7814547248d2b813b99cef7d85b62646845e5ff Mon Sep 17 00:00:00 2001 From: Wondertan Date: Thu, 30 Sep 2021 19:42:03 +0300 Subject: [PATCH 11/15] fix(node): track Start/Stop cancelation timeout with global timeout option --- node/node.go | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/node/node.go b/node/node.go index e680af185a..65b708dd5d 100644 --- a/node/node.go +++ b/node/node.go @@ -2,6 +2,8 @@ package node import ( "context" + "fmt" + "time" exchange "github.com/ipfs/go-ipfs-exchange-interface" format "github.com/ipfs/go-ipld-format" @@ -16,6 +18,8 @@ import ( "github.com/celestiaorg/celestia-node/service/block" ) +const Timeout = time.Second * 15 + var log = logging.Logger("node") // Node represents the core structure of a Celestia node. It keeps references to all Celestia-specific @@ -68,23 +72,20 @@ func New(tp Type, repo Repository) (*Node, error) { // Start launches the Node and all its components and services. func (n *Node) Start(ctx context.Context) error { - ctx, cancel := context.WithTimeout(ctx, n.app.StartTimeout()) + ctx, cancel := context.WithTimeout(ctx, Timeout) defer cancel() - log.Debugf("Starting %s Node...", n.Type) err := n.app.Start(ctx) if err != nil { - log.Errorf("Error starting %s Node: %s", n.Type, err) - return err + log.Errorf("starting %s Node: %s", n.Type, err) + return fmt.Errorf("node: faild to start: %w", err) } - - log.Infof("%s Node is started", n.Type) + log.Infof("started %s Node", n.Type) // TODO(@Wondertan): Print useful information about the node: // * API address // * Pubkey/PeerID // * Host listening address - return nil } @@ -104,17 +105,15 @@ func (n *Node) Run(ctx context.Context) error { // Canceling the given context earlier 'ctx' unblocks the Stop and aborts graceful shutdown forcing remaining // Components/Services to close immediately. func (n *Node) Stop(ctx context.Context) error { - ctx, cancel := context.WithTimeout(ctx, n.app.StopTimeout()) + ctx, cancel := context.WithTimeout(ctx, Timeout) defer cancel() - log.Debugf("Stopping %s Node...", n.Type) err := n.app.Stop(ctx) if err != nil { - log.Errorf("Error stopping %s Node: %s", n.Type, err) - return err + log.Errorf("stopping %s Node: %s", n.Type, err) + return fmt.Errorf("node: faild to stop: %w", err) } - - log.Infof("%s Node is stopped", n.Type) + log.Infof("stopped %s Node", n.Type) return nil } From 66618837ee3c699ecedad30b9525cf6cbebee55d Mon Sep 17 00:00:00 2001 From: Wondertan Date: Thu, 30 Sep 2021 19:45:31 +0300 Subject: [PATCH 12/15] feat(cmd): start command --- cmd/init.go | 4 ++-- cmd/start.go | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 cmd/start.go diff --git a/cmd/init.go b/cmd/init.go index c7942c551f..5cdaa01f4b 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -10,7 +10,7 @@ import ( // It is meant to be used a subcommand and also receive persistent flag name for repository path. func Init(repoName string, tp node.Type) *cobra.Command { if !tp.IsValid() { - panic("Init: invalid Node Type") + panic("cmd: Init: invalid Node Type") } if len(repoName) == 0 { panic("parent command must specify a persistent flag name for repository path") @@ -18,7 +18,7 @@ func Init(repoName string, tp node.Type) *cobra.Command { const cfgName = "config" cmd := &cobra.Command{ - Use: "init", + Use: "init", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { cfgF := cmd.Flag(cfgName).Value diff --git a/cmd/start.go b/cmd/start.go new file mode 100644 index 0000000000..d988bc3b81 --- /dev/null +++ b/cmd/start.go @@ -0,0 +1,60 @@ +package cmd + +import ( + "os/signal" + "syscall" + + "github.com/spf13/cobra" + + "github.com/celestiaorg/celestia-node/node" +) + +// Start constructs a CLI command to start Celestia Node daemon of the given type 'tp'. +// It is meant to be used a subcommand and also receive persistent flag name for repository path. +func Start(repoName string, tp node.Type) *cobra.Command { + if !tp.IsValid() { + panic("cmd: Start: invalid Node Type") + } + if len(repoName) == 0 { + panic("parent command must specify a persistent flag name for repository path") + } + return &cobra.Command{ + Use: "start", + Short: "Starts Node daemon. First stopping signal gracefully stops the Node and second terminates it.", + Aliases: []string{"run", "daemon"}, + Args: cobra.NoArgs, + SilenceUsage: true, + RunE: func(cmd *cobra.Command, args []string) error { + repoPath := cmd.Flag(repoName).Value.String() + + repo, err := node.Open(repoPath, tp) + if err != nil { + return err + } + + nd, err := node.New(tp, repo) + if err != nil { + return err + } + + ctx, cancel := signal.NotifyContext(cmd.Context(), syscall.SIGINT, syscall.SIGTERM) + defer cancel() + err = nd.Start(ctx) + if err != nil { + return err + } + + <-ctx.Done() + cancel() // ensure we stop reading more signals for start context + + ctx, cancel = signal.NotifyContext(cmd.Context(), syscall.SIGINT, syscall.SIGTERM) + defer cancel() + err = nd.Stop(ctx) + if err != nil { + return err + } + + return repo.Close() + }, + } +} From 769b747de4cee99c3c846e0b359565cb5e7c979c Mon Sep 17 00:00:00 2001 From: Wondertan Date: Thu, 30 Sep 2021 19:46:47 +0300 Subject: [PATCH 13/15] feat(cmd/celestia): add start command --- cmd/celestia/full.go | 9 ++++++--- cmd/celestia/light.go | 9 ++++++--- cmd/celestia/main.go | 8 ++++---- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/cmd/celestia/full.go b/cmd/celestia/full.go index 5d5439a9f7..126308b916 100644 --- a/cmd/celestia/full.go +++ b/cmd/celestia/full.go @@ -9,7 +9,10 @@ import ( func init() { const repoName = "repository" - fullCmd.AddCommand(cmd.Init(repoName, node.Full)) + fullCmd.AddCommand( + cmd.Init(repoName, node.Full), + cmd.Start(repoName, node.Full), + ) fullCmd.PersistentFlags().StringP(repoName, "r", "~/.celestia-full", @@ -18,6 +21,6 @@ func init() { } var fullCmd = &cobra.Command{ - Use: "full [subcommand]", + Use: "full [subcommand]", Args: cobra.NoArgs, -} \ No newline at end of file +} diff --git a/cmd/celestia/light.go b/cmd/celestia/light.go index db2f43ac13..b3c81fc427 100644 --- a/cmd/celestia/light.go +++ b/cmd/celestia/light.go @@ -7,9 +7,12 @@ import ( "github.com/celestiaorg/celestia-node/node" ) -func init() { +func init() { const repoName = "repository" - lightCmd.AddCommand(cmd.Init(repoName, node.Light)) + lightCmd.AddCommand( + cmd.Init(repoName, node.Light), + cmd.Start(repoName, node.Light), + ) lightCmd.PersistentFlags().StringP( repoName, "r", @@ -19,6 +22,6 @@ func init() { } var lightCmd = &cobra.Command{ - Use: "light [subcommand]", + Use: "light [subcommand]", Args: cobra.NoArgs, } diff --git a/cmd/celestia/main.go b/cmd/celestia/main.go index 40a9160ebc..917f7c5fd5 100644 --- a/cmd/celestia/main.go +++ b/cmd/celestia/main.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "os" logging "github.com/ipfs/go-log/v2" @@ -13,14 +12,15 @@ func init() { } func main() { - err := run() - if err != nil { - fmt.Fprintln(os.Stderr, err) + err := run() + if err != nil { os.Exit(1) } } func run() error { + // TODO(@Wondertan): In practise we won't need all INFO loggers from IPFS/libp2p side + // so we would need to turn off them somewhere in `logs` package. logging.SetAllLoggers(logging.LevelInfo) return rootCmd.Execute() } From f1c24ad3c25db3d7ac2139962e1d7ef459327240 Mon Sep 17 00:00:00 2001 From: Wondertan Date: Thu, 30 Sep 2021 19:51:01 +0300 Subject: [PATCH 14/15] chore(fmt): make linter happy throughout ther project --- cmd/celestia/main.go | 2 +- cmd/start.go | 8 ++++---- node/repo_test.go | 2 ++ service/block/types.go | 3 ++- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cmd/celestia/main.go b/cmd/celestia/main.go index 917f7c5fd5..ce7c19ac7b 100644 --- a/cmd/celestia/main.go +++ b/cmd/celestia/main.go @@ -19,7 +19,7 @@ func main() { } func run() error { - // TODO(@Wondertan): In practise we won't need all INFO loggers from IPFS/libp2p side + // TODO(@Wondertan): In practice we won't need all INFO loggers from IPFS/libp2p side // so we would need to turn off them somewhere in `logs` package. logging.SetAllLoggers(logging.LevelInfo) return rootCmd.Execute() diff --git a/cmd/start.go b/cmd/start.go index d988bc3b81..4cad201db1 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -19,10 +19,10 @@ func Start(repoName string, tp node.Type) *cobra.Command { panic("parent command must specify a persistent flag name for repository path") } return &cobra.Command{ - Use: "start", - Short: "Starts Node daemon. First stopping signal gracefully stops the Node and second terminates it.", - Aliases: []string{"run", "daemon"}, - Args: cobra.NoArgs, + Use: "start", + Short: "Starts Node daemon. First stopping signal gracefully stops the Node and second terminates it.", + Aliases: []string{"run", "daemon"}, + Args: cobra.NoArgs, SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { repoPath := cmd.Flag(repoName).Value.String() diff --git a/node/repo_test.go b/node/repo_test.go index 86f296b71b..4051081e56 100644 --- a/node/repo_test.go +++ b/node/repo_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" ) +//nolint:dupl func TestRepoFull(t *testing.T) { dir := t.TempDir() @@ -39,6 +40,7 @@ func TestRepoFull(t *testing.T) { assert.NotNil(t, cfg) } +//nolint:dupl func TestRepoLight(t *testing.T) { dir := t.TempDir() diff --git a/service/block/types.go b/service/block/types.go index c8361b1541..bc6e118e77 100644 --- a/service/block/types.go +++ b/service/block/types.go @@ -1,9 +1,10 @@ package block import ( - "github.com/celestiaorg/celestia-node/service/header" "github.com/celestiaorg/rsmt2d" + "github.com/celestiaorg/celestia-node/service/header" + core "github.com/celestiaorg/celestia-core/types" ) From 8082ae27486530bcb05a56e3923ec66f2366b044 Mon Sep 17 00:00:00 2001 From: rene <41963722+renaynay@users.noreply.github.com> Date: Mon, 11 Oct 2021 10:25:51 +0100 Subject: [PATCH 15/15] renes fixes --- cmd/celestia/main.go | 2 +- node/init.go | 6 +++--- node/node.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/celestia/main.go b/cmd/celestia/main.go index ce7c19ac7b..6643762709 100644 --- a/cmd/celestia/main.go +++ b/cmd/celestia/main.go @@ -26,7 +26,7 @@ func run() error { } var rootCmd = &cobra.Command{ - Use: "celestia [subcommand]", + Use: "celestia [ full || light ] [subcommand]", Short: ` / ____/__ / /__ _____/ /_(_)___ _ / / / _ \/ / _ \/ ___/ __/ / __ / diff --git a/node/init.go b/node/init.go index 0ebbc71494..03cb8263be 100644 --- a/node/init.go +++ b/node/init.go @@ -23,7 +23,6 @@ func InitWith(path string, tp Type, cfg *Config) error { return err } log.Infof("Initializing %s Node Repository over '%s'", tp, path) - defer log.Info("Node Repository initialized") err = initRoot(path) if err != nil { @@ -55,9 +54,9 @@ func InitWith(path string, tp Type, cfg *Config) error { if err != nil { return err } - log.Info("Saving config") + log.Infow("Saving config", "path", cfgPath) } else { - log.Info("Config already exists") + log.Infow("Config already exists", "path", cfgPath) } // TODO(@Wondertan): This is a lazy hack which prevents Core Repository to be generated for all case, and generates @@ -73,6 +72,7 @@ func InitWith(path string, tp Type, cfg *Config) error { return core.Init(corePath) } + log.Info("Node Repository initialized") return nil } diff --git a/node/node.go b/node/node.go index 65b708dd5d..70a065b039 100644 --- a/node/node.go +++ b/node/node.go @@ -78,7 +78,7 @@ func (n *Node) Start(ctx context.Context) error { err := n.app.Start(ctx) if err != nil { log.Errorf("starting %s Node: %s", n.Type, err) - return fmt.Errorf("node: faild to start: %w", err) + return fmt.Errorf("node: failed to start: %w", err) } log.Infof("started %s Node", n.Type)