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

Relayer: CLI tool #85

Merged
merged 28 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b05dacd
draft implementation of the CMD tool for the native relayer
sczembor Jan 9, 2025
db95ebf
add yaml config file and logic to parse it in the cmd tool
sczembor Jan 9, 2025
71521f1
error handling + use config file to init the relayer
sczembor Jan 10, 2025
4633988
white spaces
sczembor Jan 10, 2025
bb10bbb
lint + move config to a separate file
sczembor Jan 10, 2025
ac7df82
Apply suggestions from code review
sczembor Jan 10, 2025
f5f3d66
apply code review suggestions
sczembor Jan 10, 2025
f20c994
apply code review suggestions
sczembor Jan 10, 2025
02bb366
Merge branch 'master' into stan/78-cmd
sczembor Jan 13, 2025
1a6376b
merge fix
sczembor Jan 13, 2025
2d6931a
apply code review suggesitons
sczembor Jan 13, 2025
b86d3f4
config structure
sczembor Jan 13, 2025
53ffbb1
remove unused config
sczembor Jan 13, 2025
342cfcb
update the function to accept a lvl argument
sczembor Jan 13, 2025
c16b0da
Merge branch 'master' into stan/78-cmd
sczembor Jan 13, 2025
7f05352
remove mock btc client
sczembor Jan 13, 2025
83dfbe0
add network type
sczembor Jan 13, 2025
45356b0
update tags + add unit test
sczembor Jan 14, 2025
43e67d5
Apply suggestions from code review
sczembor Jan 14, 2025
e37f79c
create a helper function to prepare env
sczembor Jan 14, 2025
27be8c5
Update cmd/native-relayer/cli/start.go
sczembor Jan 14, 2025
09ddd9c
divide the start into smaller chunks, remove unecesary json tags
sczembor Jan 14, 2025
53a336d
fix linter
sczembor Jan 14, 2025
b8173b3
mispelling
sczembor Jan 14, 2025
142bc6f
apply code review suggestions
sczembor Jan 14, 2025
bec097c
Merge branch 'master' into stan/78-cmd
sczembor Jan 14, 2025
0f917f0
linter
sczembor Jan 14, 2025
3d0ec15
Merge branch 'stan/78-cmd' of https://github.com/gonative-cc/relayer …
sczembor Jan 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions cmd/native-relayer/cli/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package cli

import "time"

// Configuration struct
type Config struct {
Native NativeCfg `mapstructure:"native"`
Ika IkaCfg `mapstructure:"ika"`
Btc BitcoinCfg `mapstructure:"bitcoin"`
Relayer RelayerCfg `mapstructure:"relayer"`
DB DBCfg `mapstructure:"db"`
}

type NativeCfg struct {
RPC string `mapstructure:"native_rpc"`
GRPC string `mapstructure:"native_grpc"`
}

type IkaCfg struct {
RPC string `mapstructure:"ika_rpc"`
SignerMnemonic string `mapstructure:"ika_signer_mnemonic"`
NativeLcPackage string `mapstructure:"ika_native_lc_package"`
NativeLcModule string `mapstructure:"ika_native_lc_module"`
NativeLcFunction string `mapstructure:"ika_native_lc_function"`
GasAcc string `mapstructure:"ika_gas_acc"`
GasBudget string `mapstructure:"ika_gas_budget"`
}

type BitcoinCfg struct {
RPCHost string `mapstructure:"btc_rpc_host"`
RPCUser string `mapstructure:"btc_rpc_user"`
RPCPass string `mapstructure:"btc_rpc_pass"`
ConfirmationThreshold uint8 `mapstructure:"btc_confirmation_threshold"`
sczembor marked this conversation as resolved.
Show resolved Hide resolved
HTTPPostMode bool `mapstructure:"http_post_mode"`
DisableTLS bool `mapstructure:"disable_tls"`
Network string `mapstructure:"network"`
}

type RelayerCfg struct {
ProcessTxsInterval time.Duration `mapstructure:"process_txs_interval"`
ConfirmTxsInterval time.Duration `mapstructure:"confirm_txs_interval"`
SignReqFetchInterval time.Duration `mapstructure:"sign_req_fetch_interval"`
SignReqFetchFrom int `mapstructure:"sign_req_fetch_from"`
SignReqFetchLimit int `mapstructure:"sign_req_fetch_limit"`
}

type DBCfg struct {
File string `mapstructure:"db_file"`
}
robert-zaremba marked this conversation as resolved.
Show resolved Hide resolved
35 changes: 35 additions & 0 deletions cmd/native-relayer/cli/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package cli

import (
"os"

"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

var (
configFile string
logLevel string

rootCmd = &cobra.Command{
Use: "relayer-cli",
Short: "CLI tool for managing the relayer",
}
)

func Execute() {
if err := rootCmd.Execute(); err != nil {
log.Error().Err(err).Msg("CLI execution failed")
os.Exit(1)
}
}

func init() {
rootCmd.PersistentFlags().StringVar(&configFile, "config", "", "Path to the config file")
rootCmd.PersistentFlags().StringVar(
&logLevel, "log-level",
"",
"Set the log level (trace, debug, info, warn, error, fatal, panic)",
)
rootCmd.AddCommand(startCmd)
}
147 changes: 147 additions & 0 deletions cmd/native-relayer/cli/start.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package cli

import (
"context"
"os"
"os/signal"
"sync"
"syscall"

"github.com/block-vision/sui-go-sdk/signer"
"github.com/block-vision/sui-go-sdk/sui"
"github.com/btcsuite/btcd/rpcclient"
"github.com/gonative-cc/relayer/dal"
"github.com/gonative-cc/relayer/env"
"github.com/gonative-cc/relayer/ika"
"github.com/gonative-cc/relayer/ika2btc"
"github.com/gonative-cc/relayer/native"
"github.com/gonative-cc/relayer/native2ika"
"github.com/gonative-cc/relayer/nbtc"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

var startCmd = &cobra.Command{
Use: "start",
Short: "Starts the relayer",
Run: func(cmd *cobra.Command, args []string) {
lvl, err := cmd.Root().PersistentFlags().GetString("log-level")
sczembor marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
log.Error().Err(err).Msg("Error getting log level")
os.Exit(1)
}
logLvl, err := zerolog.ParseLevel(lvl)
if err != nil {
log.Error().Err(err).Msg("Error parsing log level")
os.Exit(1)
}
env.InitLogger(logLvl)
configFile, err := cmd.Root().PersistentFlags().GetString("config")
sczembor marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
log.Error().Err(err).Msg("Error getting config file path")
os.Exit(1)
}

config, err := loadConfig(configFile)
if err != nil {
log.Error().Err(err).Msg("Error loading config")
os.Exit(1)
}
sczembor marked this conversation as resolved.
Show resolved Hide resolved
db, err := dal.NewDB(config.DB.File)
if err != nil {
log.Error().Err(err).Msg("Error creating database")
os.Exit(1)
}
if err := db.InitDB(); err != nil {
log.Error().Err(err).Msg("Error initializing database")
os.Exit(1)
}
sczembor marked this conversation as resolved.
Show resolved Hide resolved
suiClient := sui.NewSuiClient(config.Ika.RPC).(*sui.Client)
if suiClient == nil {
log.Error().Err(err).Msg("Error creating Sui client")
os.Exit(1)
}
signer, err := signer.NewSignertWithMnemonic(config.Ika.SignerMnemonic)
if err != nil {
log.Error().Err(err).Msg("Error creating signer with mnemonic")
os.Exit(1)
}
ikaClient, err := ika.NewClient(
suiClient,
signer,
ika.SuiCtrCall{
Package: config.Ika.NativeLcPackage,
Module: config.Ika.NativeLcModule,
Function: config.Ika.NativeLcFunction,
},
ika.SuiCtrCall{
Package: config.Ika.NativeLcPackage,
Module: config.Ika.NativeLcModule,
Function: config.Ika.NativeLcFunction,
},
config.Ika.GasAcc,
config.Ika.GasBudget,
)
if err != nil {
log.Error().Err(err).Msg("Error creating IKA client")
os.Exit(1)
}
sczembor marked this conversation as resolved.
Show resolved Hide resolved
btcProcessor, err := ika2btc.NewProcessor(
rpcclient.ConnConfig{
sczembor marked this conversation as resolved.
Show resolved Hide resolved
Host: config.Btc.RPCHost,
User: config.Btc.RPCUser,
Pass: config.Btc.RPCPass,
HTTPPostMode: config.Btc.HTTPPostMode,
DisableTLS: config.Btc.DisableTLS,
Params: config.Btc.Network,
},
config.Btc.ConfirmationThreshold,
db,
)
sczembor marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
log.Error().Err(err).Msg("Error creating Bitcoin processor")
os.Exit(1)
}
nativeProcessor := native2ika.NewProcessor(ikaClient, db)
// TODO: replace with the the real endpoint once available
fetcher, err := native.NewMockAPISignRequestFetcher()
if err != nil {
log.Error().Err(err).Msg("Error creating SignReq fetcher ")
os.Exit(1)
}
relayer, err := nbtc.NewRelayer(
nbtc.RelayerConfig{
ProcessTxsInterval: config.Relayer.ProcessTxsInterval,
ConfirmTxsInterval: config.Relayer.ConfirmTxsInterval,
SignReqFetchInterval: config.Relayer.SignReqFetchInterval,
SignReqFetchFrom: config.Relayer.SignReqFetchFrom,
SignReqFetchLimit: config.Relayer.SignReqFetchLimit,
},
db,
nativeProcessor,
btcProcessor,
fetcher,
)
if err != nil {
log.Error().Err(err).Msg("Error creating relayer")
os.Exit(1)
}
var wg sync.WaitGroup
wg.Add(1)
sczembor marked this conversation as resolved.
Show resolved Hide resolved
go func() {
defer wg.Done()
if err := relayer.Start(context.Background()); err != nil {
sczembor marked this conversation as resolved.
Show resolved Hide resolved
log.Error().Err(err).Msg("Relayer encountered an error")
}
}()
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)

<-c
log.Info().Msg("Stopping the relayer...")
relayer.Stop()
wg.Wait()
log.Info().Msg("Relayer stopped.")
},
}
32 changes: 32 additions & 0 deletions cmd/native-relayer/cli/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package cli

import (
"fmt"

"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)

func loadConfig(configFile string) (*Config, error) {
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AddConfigPath("$HOME/.native-relayer")
sczembor marked this conversation as resolved.
Show resolved Hide resolved
if configFile != "" {
viper.SetConfigFile(configFile)
}
robert-zaremba marked this conversation as resolved.
Show resolved Hide resolved
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
return nil, fmt.Errorf("error reading config file: %w", err)
}
}
var config Config
if err := viper.Unmarshal(&config); err != nil {
return nil, fmt.Errorf("error unmarshalling config: %w", err)
}

log.Info().Msg("Loaded Configuration:")
log.Info().Interface("config", config).Msg("")

return &config, nil
}
33 changes: 33 additions & 0 deletions cmd/native-relayer/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Relayer Configuration

native:
native_rpc: "127.0.0.1:26657"
native_grpc: "127.0.0.1:9090"

ika:
ika_rpc: "127.0.0.1:0001"
ika_signer_mnemonic: ""
ika_native_lc_package: ""
ika_native_lc_module: ""
ika_native_lc_function: ""
ika_gas_acc: ""
ika_gas_budget: ""

bitcoin:
btc_rpc_host: "your-bitcoin-rpc.com"
btc_rpc_user: "your-bitcoin-rpc-user"
btc_rpc_pass: "your-bitcoin-rpc-password"
btc_confirmation_threshold: 6
http_post_mode: true
disable_tls: false
network: "testnet"

relayer:
process_txs_interval: 5s
confirm_txs_interval: 7s
sign_req_fetch_interval: 5s
sign_req_fetch_from: 0
sign_req_fetch_limit: 5

db:
db_file: "relayer.db"
sczembor marked this conversation as resolved.
Show resolved Hide resolved
7 changes: 7 additions & 0 deletions cmd/native-relayer/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

import "github.com/gonative-cc/relayer/cmd/native-relayer/cli"

func main() {
cli.Execute()
}
11 changes: 3 additions & 8 deletions nbtc/relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ type Relayer struct {

// RelayerConfig holds the configuration parameters for the Relayer.
type RelayerConfig struct {
ProcessTxsInterval time.Duration `json:"processTxsInterval"`
ConfirmTxsInterval time.Duration `json:"confirmTxsInterval"`
SignReqFetchInterval time.Duration `json:"signReqFetchInterval"`
ConfirmationThreshold uint8 `json:"confirmationThreshold"`
ProcessTxsInterval time.Duration `json:"processTxsInterval"`
ConfirmTxsInterval time.Duration `json:"confirmTxsInterval"`
SignReqFetchInterval time.Duration `json:"signReqFetchInterval"`
sczembor marked this conversation as resolved.
Show resolved Hide resolved
// ID of the first sign req that we want to fetch in
SignReqFetchFrom int `json:"signReqFetchFrom"`
SignReqFetchLimit int `json:"signReqFetchLimit"`
Expand Down Expand Up @@ -82,10 +81,6 @@ func NewRelayer(
relayerConfig.SignReqFetchInterval = time.Second * 10
}

if relayerConfig.ConfirmationThreshold == 0 {
relayerConfig.ConfirmationThreshold = 6
}

return &Relayer{
db: db,
nativeProcessor: nativeProcessor,
Expand Down
9 changes: 4 additions & 5 deletions nbtc/relayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,10 @@ var btcClientConfig = rpcclient.ConnConfig{
}

var relayerConfig = RelayerConfig{
ProcessTxsInterval: time.Second * 5,
ConfirmTxsInterval: time.Second * 7,
ConfirmationThreshold: 6,
SignReqFetchFrom: 0,
SignReqFetchLimit: 5,
ProcessTxsInterval: time.Second * 5,
ConfirmTxsInterval: time.Second * 7,
SignReqFetchFrom: 0,
SignReqFetchLimit: 5,
}

// setupTestProcessor initializes the common dependencies
Expand Down
Loading