Skip to content

Commit

Permalink
Merge pull request #33 from bandprotocol/separate-store-app
Browse files Browse the repository at this point in the history
add store object
  • Loading branch information
nkitlabs authored Feb 26, 2025
2 parents 2839125 + e5dd360 commit f787675
Show file tree
Hide file tree
Showing 35 changed files with 1,440 additions and 721 deletions.
31 changes: 29 additions & 2 deletions relayer/log.go → cmd/log.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package relayer
package cmd

import (
"fmt"
"os"
"time"

zaplogfmt "github.com/jsternberg/zap-logfmt"
"github.com/spf13/viper"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

func newRootLogger(format string, logLevel string) (*zap.Logger, error) {
// newLogger creates a new root logger with the given log format and log level.
func newLogger(format string, logLevel string) (*zap.Logger, error) {
config := zap.NewProductionEncoderConfig()
config.EncodeTime = func(ts time.Time, encoder zapcore.PrimitiveArrayEncoder) {
encoder.AppendString(ts.UTC().Format("2006-01-02T15:04:05.000000Z07:00"))
Expand Down Expand Up @@ -51,3 +53,28 @@ func newRootLogger(format string, logLevel string) (*zap.Logger, error) {

return logger, nil
}

// initLogger initializes the logger with the given default log level.
func initLogger(defaultLogLevel string) (log *zap.Logger, err error) {
logFormat := viper.GetString("log-format")

logLevel := viper.GetString("log-level")
if viper.GetBool("debug") {
logLevel = "debug"
}
if logLevel == "" && defaultLogLevel != "" {
logLevel = defaultLogLevel
}

// initialize logger only if user run command "start" or log level is "debug"
if os.Args[1] == "start" || logLevel == "debug" {
log, err = newLogger(logFormat, logLevel)
if err != nil {
return nil, err
}
} else {
log = zap.NewNop()
}

return log, nil
}
36 changes: 28 additions & 8 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,22 @@ import (
"go.uber.org/zap"

falcon "github.com/bandprotocol/falcon/relayer"
"github.com/bandprotocol/falcon/relayer/store"
)

const (
appName = "falcon"
defaultCoinType = 60

PassphraseEnvKey = "PASSPHRASE"
)

var defaultHome = filepath.Join(os.Getenv("HOME"), ".falcon")

// NewRootCmd returns the root command for falcon.
func NewRootCmd(log *zap.Logger) *cobra.Command {
app := falcon.NewApp(log, defaultHome, false, nil)
passphrase := os.Getenv(PassphraseEnvKey)
app := falcon.NewApp(log, defaultHome, false, nil, passphrase, nil)

// RootCmd represents the base command when called without any subcommands
rootCmd := &cobra.Command{
Expand All @@ -44,16 +48,32 @@ func NewRootCmd(log *zap.Logger) *cobra.Command {
(i.e. 'falcon tx', 'falcon q', etc...)`),
}

rootCmd.PersistentPreRunE = func(cmd *cobra.Command, _ []string) error {
// retrieve log level from viper
logLevelViper := viper.GetString("log-level")
if viper.GetBool("debug") {
logLevelViper = "debug"
rootCmd.PersistentPreRunE = func(cmd *cobra.Command, _ []string) (err error) {
// set up store
app.Store, err = store.NewFileSystem(app.HomePath)
if err != nil {
return err
}

// load configuration
app.Config, err = app.Store.GetConfig()
if err != nil {
return err
}

logFormat := viper.GetString("log-format")
// retrieve log level from config
configLogLevel := ""
if app.Config != nil {
configLogLevel = app.Config.Global.LogLevel
}

// init log object
app.Log, err = initLogger(configLogLevel)
if err != nil {
return err
}

return app.Init(rootCmd.Context(), logLevelViper, logFormat)
return app.Init(rootCmd.Context())
}

rootCmd.PersistentPostRun = func(cmd *cobra.Command, _ []string) {
Expand Down
66 changes: 66 additions & 0 deletions internal/os/os.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package os

import (
"os"
"path"
)

// CheckAndCreateFolder checks if the folder exists and creates it if it doesn't.
func CheckAndCreateFolder(path string) error {
if exist, err := IsPathExist(path); err != nil {
return err
} else if !exist {
return os.Mkdir(path, os.ModePerm)
}

return nil
}

// IsPathExist checks if the path exists.
func IsPathExist(path string) (bool, error) {
if _, err := os.Stat(path); os.IsNotExist(err) {
return false, nil
} else if err != nil {
return false, err
}

return true, nil
}

// ReadFileIfExist reads file from the given path. It returns empty data with no error,
// if the file doesn't exist. Otherwise, it returns an error.
func ReadFileIfExist(path string) ([]byte, error) {
if exist, err := IsPathExist(path); err != nil {
return nil, err
} else if !exist {
return nil, nil
}

return os.ReadFile(path)
}

// Write writes the given data to the file at the given path. It also creates the folders if they don't exist.
func Write(data []byte, paths []string) error {
// Create folders if they don't exist
folderPath := ""
for _, p := range paths[:len(paths)-1] {
folderPath = path.Join(folderPath, p)
if err := CheckAndCreateFolder(folderPath); err != nil {
return err
}
}

// Write the data to the file
filePath := path.Join(folderPath, paths[len(paths)-1])
f, err := os.Create(filePath)
if err != nil {
return err
}
defer f.Close()

if _, err = f.Write(data); err != nil {
return err
}

return nil
}
97 changes: 97 additions & 0 deletions internal/os/os_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package os_test

import (
"os"
"path"
"testing"

"github.com/stretchr/testify/require"

internal_os "github.com/bandprotocol/falcon/internal/os"
)

func TestCheckAndCreateFolder(t *testing.T) {
tmpDir := path.Join(t.TempDir(), "test")

// create a folder
err := internal_os.CheckAndCreateFolder(tmpDir)
require.NoError(t, err)

_, err = os.Stat(tmpDir)
require.NoError(t, err)

// create a folder again; shouldn't cause any error
err = internal_os.CheckAndCreateFolder(tmpDir)
require.NoError(t, err)
}

func TestIsPathExist(t *testing.T) {
tmpDir := path.Join(t.TempDir(), "test")

// check if a folder exists, should return false
exist, err := internal_os.IsPathExist(tmpDir)
require.NoError(t, err)
require.False(t, exist)

err = internal_os.CheckAndCreateFolder(tmpDir)
require.NoError(t, err)

exist, err = internal_os.IsPathExist(tmpDir)
require.NoError(t, err)
require.True(t, exist)
}

func TestWrite(t *testing.T) {
tmpDir := path.Join(t.TempDir(), "test")

// write a file
err := internal_os.Write([]byte("test"), []string{tmpDir, "test.txt"})
require.NoError(t, err)

// check if the file exists
exist, err := internal_os.IsPathExist(path.Join(tmpDir, "test.txt"))
require.NoError(t, err)
require.True(t, exist)

// check if the file contains the correct data
data, err := os.ReadFile(path.Join(tmpDir, "test.txt"))
require.NoError(t, err)
require.Equal(t, "test", string(data))

// write a file again; shouldn't cause any error
err = internal_os.Write([]byte("new test"), []string{tmpDir, "test.txt"})
require.NoError(t, err)

// check if the file contains the correct data
data, err = os.ReadFile(path.Join(tmpDir, "test.txt"))
require.NoError(t, err)
require.Equal(t, "new test", string(data))
}

func TestReadFileIfExist(t *testing.T) {
tmpDir := path.Join(t.TempDir(), "test")

// check if a file exists, should return nil
data, err := internal_os.ReadFileIfExist(path.Join(tmpDir, "test.txt"))
require.NoError(t, err)
require.Nil(t, data)

// write a file
err = internal_os.Write([]byte("test"), []string{tmpDir, "test.txt"})
require.NoError(t, err)

// check if the file exists
exist, err := internal_os.IsPathExist(path.Join(tmpDir, "test.txt"))
require.NoError(t, err)
require.True(t, exist)

// check if the file contains the correct data
data, err = internal_os.ReadFileIfExist(path.Join(tmpDir, "test.txt"))
require.NoError(t, err)
require.Equal(t, "test", string(data))

// check if a file doesn't exist, should return nil
data, err = internal_os.ReadFileIfExist(path.Join(tmpDir, "non-exist.txt"))
require.NoError(t, err)
require.Nil(t, data)
}
8 changes: 4 additions & 4 deletions internal/relayertest/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import (
_ "embed"
"time"

falcon "github.com/bandprotocol/falcon/relayer"
"github.com/bandprotocol/falcon/relayer/band"
"github.com/bandprotocol/falcon/relayer/chains"
"github.com/bandprotocol/falcon/relayer/chains/evm"
"github.com/bandprotocol/falcon/relayer/config"
)

//go:embed testdata/default_config.toml
Expand All @@ -19,8 +19,8 @@ var CustomCfgText string
//go:embed testdata/custom_config_with_time_str.toml
var CustomCfgTextWithTimeStr string

var CustomCfg = falcon.Config{
Global: falcon.GlobalConfig{
var CustomCfg = config.Config{
Global: config.GlobalConfig{
CheckingPacketInterval: 1 * time.Minute,
SyncTunnelsInterval: 5 * time.Minute,
PenaltySkipRounds: 3,
Expand All @@ -31,7 +31,7 @@ var CustomCfg = falcon.Config{
Timeout: 3 * time.Second,
LivelinessCheckingInterval: 5 * time.Minute,
},
TargetChains: chains.ChainProviderConfigs{
TargetChains: config.ChainProviderConfigs{
"testnet": &evm.EVMChainProviderConfig{
BaseChainProviderConfig: chains.BaseChainProviderConfig{
Endpoints: []string{"http://localhost:8545"},
Expand Down
Loading

0 comments on commit f787675

Please sign in to comment.