Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion src/shidai/internal/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/gin-gonic/gin"
"github.com/kiracore/sekin/src/shidai/internal/commands"
interxhandler "github.com/kiracore/sekin/src/shidai/internal/interx_handler"
"github.com/kiracore/sekin/src/shidai/internal/logger"
"github.com/kiracore/sekin/src/shidai/internal/types"
"github.com/kiracore/sekin/src/shidai/internal/update"
Expand All @@ -28,12 +29,12 @@ func Serve() {
router.GET("/dashboard", getDashboardHandler())
router.POST("/config", getCurrentConfigs())
router.PUT("/config", setConfig())


updateContext := context.Background()

go backgroundUpdate()
go update.UpdateRunner(updateContext)
go interxhandler.AddrbookManager(context.Background())
if err := router.Run(":8282"); err != nil {
log.Error("Failed to start the server", zap.Error(err))
}
Expand Down
4 changes: 2 additions & 2 deletions src/shidai/internal/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ func handleJoinCommand(args map[string]interface{}) (string, error) {
if err != nil {
return "", fmt.Errorf("unable to init interx: %w", err)
}
err = interxhandler.StartInterx()
err = interxhandler.StartInterx(ctx)
if err != nil {
return "", fmt.Errorf("unable to start interx: %w", err)
}
Expand Down Expand Up @@ -262,7 +262,7 @@ func handleStartComamnd(args map[string]interface{}) (string, error) {
return "", err
}

err = interxhandler.StartInterx()
err = interxhandler.StartInterx(ctx)
if err != nil {
return "", fmt.Errorf("unable to start interx: %w", err)
}
Expand Down
57 changes: 56 additions & 1 deletion src/shidai/internal/interx_handler/interx_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import (
"errors"
"fmt"
"io"
"time"

mnemonicsgenerator "github.com/KiraCore/tools/validator-key-gen/MnemonicsGenerator"
"go.uber.org/zap"

httpexecutor "github.com/kiracore/sekin/src/shidai/internal/http_executor"
"github.com/kiracore/sekin/src/shidai/internal/logger"
"github.com/kiracore/sekin/src/shidai/internal/types"
"github.com/kiracore/sekin/src/shidai/internal/utils"
)

var log = logger.GetLogger()
Expand All @@ -32,6 +35,7 @@ func InitInterx(ctx context.Context, masterMnemonicSet *mnemonicsgenerator.Maste
"signing_mnemonic": signerMnemonic,
"port": fmt.Sprintf("%v", types.DEFAULT_INTERX_PORT),
"validator_node_id": string(masterMnemonicSet.ValidatorNodeId),
"addrbook": types.INTERX_ADDRBOOK_PATH,
},
}
out, err := httpexecutor.ExecuteCallerCommand(types.INTERX_CONTAINER_ADDRESS, "8081", "POST", cmd)
Expand All @@ -43,7 +47,7 @@ func InitInterx(ctx context.Context, masterMnemonicSet *mnemonicsgenerator.Maste
return nil
}

func StartInterx() error {
func StartInterx(ctx context.Context) error {
cmd := httpexecutor.CommandRequest{
Command: "start",
Args: map[string]interface{}{
Expand All @@ -61,3 +65,54 @@ func StartInterx() error {

return nil
}

// run this in goroutine
func AddrbookManager(ctx context.Context) {
ticker := time.NewTicker(30 * time.Minute)
defer ticker.Stop()
errorCooldown := time.Second * 1

err := addrbookCopy()
if err != nil {
log.Debug("Error when replacing interx addrbook with sekai addrbook, sleeping", zap.Duration("errorCooldown", errorCooldown))
time.Sleep(errorCooldown)
}
for {
select {
case <-ctx.Done():
fmt.Println("Stopping the addrbookManager loop")
return
case t := <-ticker.C:
for {
err := addrbookCopy()
if err != nil {
log.Debug("Error when replacing interx addrbook with sekai addrbook, sleeping", zap.Duration("errorCooldown", errorCooldown))
time.Sleep(errorCooldown)
continue
}
log.Debug("Address book copying was executed", zap.Time("ticker", t))
break
}
}
}
}

func addrbookCopy() error {
var equal, interxAddrbookExist bool
var err error
interxAddrbookExist = utils.FileExists(types.INTERX_ADDRBOOK_PATH)
if interxAddrbookExist {
equal, err = utils.FilesAreEqualMD5(types.SEKAI_ADDRBOOK_PATH, types.INTERX_ADDRBOOK_PATH)
if err != nil {
return fmt.Errorf("error when comparing sekai and interx address books: %w", err)
}
}
if !equal || !interxAddrbookExist {
err := utils.SafeCopy(types.SEKAI_ADDRBOOK_PATH, types.INTERX_ADDRBOOK_PATH)
if err != nil {
return fmt.Errorf("error when replacing interx addrbook with sekai addrbook: %w", err)
}
}

return nil
}
4 changes: 4 additions & 0 deletions src/shidai/internal/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ const (
DEFAULT_RPC_PORT int = 26657
DEFAULT_GRPC_PORT int = 9090

SEKAI_CONFIG_FOLDER string = SEKAI_HOME + "/config"
INTERX_ADDRBOOK_PATH string = INTERX_HOME + "/addrbook.json"
SEKAI_ADDRBOOK_PATH string = SEKAI_CONFIG_FOLDER + "/addrbook.json"

SEKAI_CONTAINER_ADDRESS string = "sekai.local"
INTERX_CONTAINER_ADDRESS string = "interx.local"

Expand Down
125 changes: 125 additions & 0 deletions src/shidai/internal/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package utils

import (
"bytes"
"crypto/md5"
"crypto/rand"
"encoding/hex"
"encoding/json"
"fmt"
"io"
Expand All @@ -11,6 +13,7 @@ import (
"os"
"reflect"
"regexp"
"syscall"

"github.com/BurntSushi/toml"
"github.com/kiracore/sekin/src/shidai/internal/logger"
Expand Down Expand Up @@ -336,3 +339,125 @@ func CheckForExtraFields(structure interface{}, rawMap map[string]interface{}) e

return nil
}
func SafeCopy(src, dst string) error {
log.Debug("Trying to copy <%v> to <%v>", zap.String("source:", src), zap.String("destination:", dst))
check := FileExists(src)
if !check {
return fmt.Errorf("source file does not exist")
}

info, err := os.Stat(dst)
if err == nil {
if info.IsDir() {
return fmt.Errorf("destination path <%v> is a folder, cannot overwrite", dst)
}
} else if !os.IsNotExist(err) {
return fmt.Errorf("failed to access destination path <%v>: %w", dst, err)
}

srcFile, err := os.Open(src)
if err != nil {
return fmt.Errorf("failed to open source file: %w", err)
}
defer srcFile.Close()

if err := syscall.Flock(int(srcFile.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
if err == syscall.EWOULDBLOCK {
return fmt.Errorf("file is locked: %w", err)
} else {
return fmt.Errorf("failed to lock source file: %w", err)
}
}

defer syscall.Flock(int(srcFile.Fd()), syscall.LOCK_UN)

dstFile, err := os.Create(dst)
if err != nil {
return fmt.Errorf("failed to create destination file: %w", err)
}
defer dstFile.Close()

if err := syscall.Flock(int(dstFile.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
if err == syscall.EWOULDBLOCK {
return fmt.Errorf("destination file is locked: %w", err)
} else {
return fmt.Errorf("failed to lock destination file: %w", err)
}
}
defer syscall.Flock(int(dstFile.Fd()), syscall.LOCK_UN)

if _, err := io.Copy(dstFile, srcFile); err != nil {
return fmt.Errorf("failed to copy file: %w", err)
}

log.Debug("File copied", zap.String("source:", src), zap.String("destination:", dst))
return nil
}

func FilesAreEqual(file1, file2 string) (bool, error) {
f1, err := os.Open(file1)
if err != nil {
return false, fmt.Errorf("failed to open file1: %w", err)
}
defer f1.Close()

f2, err := os.Open(file2)
if err != nil {
return false, fmt.Errorf("failed to open file2: %w", err)
}
defer f2.Close()

buf1 := make([]byte, 1024)
buf2 := make([]byte, 1024)

for {
n1, err1 := f1.Read(buf1)
n2, err2 := f2.Read(buf2)

if err1 != nil && err1 != io.EOF {
return false, fmt.Errorf("failed to read from file1: %w", err1)
}
if err2 != nil && err2 != io.EOF {
return false, fmt.Errorf("failed to read from file2: %w", err2)
}

if n1 != n2 || !bytes.Equal(buf1[:n1], buf2[:n2]) {
return false, nil
}

if err1 == io.EOF && err2 == io.EOF {
break
}
}

return true, nil
}

func FilesAreEqualMD5(file1, file2 string) (bool, error) {
hash1, err := HashFileMD5(file1)
if err != nil {
return false, fmt.Errorf("failed to hash file1: %w", err)
}

hash2, err := HashFileMD5(file2)
if err != nil {
return false, fmt.Errorf("failed to hash file2: %w", err)
}

return hash1 == hash2, nil
}

func HashFileMD5(filename string) (string, error) {
f, err := os.Open(filename)
if err != nil {
return "", fmt.Errorf("failed to open file: %w", err)
}
defer f.Close()

hasher := md5.New()
if _, err := io.Copy(hasher, f); err != nil {
return "", fmt.Errorf("failed to hash file: %w", err)
}

return hex.EncodeToString(hasher.Sum(nil)), nil
}
Loading