Skip to content

Commit

Permalink
Merge pull request #35 from KiraCore/feature/tx_control
Browse files Browse the repository at this point in the history
Feature/tx control
  • Loading branch information
MrLutik authored Jun 8, 2024
2 parents 510939b + 675f3d8 commit b9d6d00
Show file tree
Hide file tree
Showing 11 changed files with 366 additions and 90 deletions.
59 changes: 59 additions & 0 deletions scripts/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,35 @@ SEKIN_DIR="$KM_DIR/sekin"
COMPOSE_URL="https://raw.githubusercontent.com/KiraCore/sekin/main/compose.yml"
COMPOSE_PATH="/home/km/sekin/compose.yml"

# DEPLOY
SEKAI_VER=""
INTERX_VER=""

for arg in "$@"; do
case $arg in
--sekai=*)
SEKAI_VER="${arg#*=}"
shift
;;
--interx=*)
INTERX_VER="${arg#*=}"
shift
;;
esac
done

# Validate the version format and existence, warn if not provided or incorrect
if [[ -z "$SEKAI_VER" || ! $SEKAI_VER =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Warning: Invalid or missing SEKAI version. Continuing with default or previously set version."
fi

if [[ -z "$INTERX_VER" || ! $INTERX_VER =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Warning: Invalid or missing INTERX version. Continuing with default or previously set version."
fi

echo "Using SEKAI version: $SEKAI_VER"
echo "Using INTERX version: $INTERX_VER"

# Function to update system
update_system() {
echo "Updating system..."
Expand Down Expand Up @@ -219,6 +248,35 @@ clone_repo_as_km() {
fi
}

update_services_versions() {
local compose_path="$COMPOSE_PATH"
local sekai_ver="$SEKAI_VER"
local interx_ver="$INTERX_VER"

# Check if the compose file exists
if [ ! -f "$compose_path" ]; then
echo "Compose file does not exist at the specified path: $compose_path"
return 1
fi

# Check and update SEKAI version if provided and not empty
if [[ -n "$sekai_ver" && $sekai_ver =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
sed -i "s|ghcr.io/kiracore/sekin/sekai:v[0-9.]*|ghcr.io/kiracore/sekin/sekai:$sekai_ver|g" "$compose_path"
echo "Updated SEKAI version to $sekai_ver in $compose_path"
else
echo "No valid SEKAI version provided, skipping update."
fi

# Check and update INTERX version if provided and not empty
if [[ -n "$interx_ver" && $interx_ver =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
sed -i "s|ghcr.io/kiracore/sekin/interx:v[0-9.]*|ghcr.io/kiracore/sekin/interx:$interx_ver|g" "$compose_path"
echo "Updated INTERX version to $interx_ver in $compose_path"
else
echo "No valid INTERX version provided, skipping update."
fi

}

main() {
update_system
install_prerequisites
Expand All @@ -227,6 +285,7 @@ main() {
add_user_km
add_km_to_docker_group
download_compose_and_change_owner
update_services_versions
# clone_repo_as_km
run_docker_compose_as_km
}
Expand Down
1 change: 1 addition & 0 deletions src/shidai/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/cosmos/go-bip39 v1.0.0
github.com/docker/docker v23.0.1+incompatible
github.com/gin-gonic/gin v1.10.0
github.com/google/uuid v1.6.0
github.com/nxadm/tail v1.4.11
github.com/spf13/cobra v1.8.0
github.com/tyler-smith/go-bip39 v1.1.0
Expand Down
2 changes: 2 additions & 0 deletions src/shidai/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
Expand Down
50 changes: 50 additions & 0 deletions src/shidai/internal/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"strconv"

"github.com/kiracore/sekin/src/shidai/internal/docker"
interxhandler "github.com/kiracore/sekin/src/shidai/internal/interx_handler"
interxhelper "github.com/kiracore/sekin/src/shidai/internal/interx_handler/interx_helper"
"github.com/kiracore/sekin/src/shidai/internal/logger"
Expand Down Expand Up @@ -43,6 +44,7 @@ var (
"join": handleJoinCommand,
"status": handleStatusCommand,
"start": handleStartComamnd,
"tx": handleTxCommand,
}
)

Expand All @@ -68,6 +70,54 @@ func ExecuteCommandHandler(c *gin.Context) {
}

// [COMMANDS] //
func handleTxCommand(args map[string]interface{}) (string, error) {
cmd, ok := args["tx"].(string)
if !ok {
log.Error("Transaction command is missing or not a string")
return "", types.ErrInvalidOrMissingTx
}

cm, err := docker.NewContainerManager()
if err != nil {
log.Error("Failed to initialize Docker API", zap.Error(err))
return "", fmt.Errorf("failed to initialize docker API: %w", err)
}

ctx := context.Background()
containerID := types.SEKAI_CONTAINER_ID
var command []string

if cmd == "claim_seat" {
moniker, ok := args["moniker"].(string)
if !ok {
moniker = utils.GenerateRandomString(8)
log.Warn("Moniker was not provided. Generated randomly.", zap.String("moniker", moniker))
}
args["moniker"] = moniker
}

switch cmd {
case "activate":
command = []string{"sekaid", "tx", "customslashing", "activate", "--from", "validator", "--keyring-backend", "test", "--home", "$SEKAID_HOME", "--chain-id", "$NETWORK_NAME", "--fees", "1000ukex", "--gas", "1000000", "--node", "tcp://sekai.local:26657", "--broadcast-mode", "async", "--yes"}
case "pause", "upause":
action := map[string]string{"pause": "inactivate", "upause": "unpause"}[cmd]
command = []string{"sekaid", "tx", "customslashing", action, "--from", "validator", "--keyring-backend", "test", "--home", "/sekai", "--chain-id", "$NETWORK_NAME", "--fees", "1000ukex", "--gas", "1000000", "--node", "tcp://sekai.local:26657", "--broadcast-mode", "async", "--yes"}
case "claim_seat":
command = []string{"sekaid", "tx", "customstaking", "claim-validator-seat", "--from", "validator", "--keyring-backend", "test", "--home", "/sekai", "--moniker", args["moniker"].(string), "--chain-id", "$NETWORK_NAME", "--gas", "1000000", "--node", "tcp://sekai.local:26657", "--broadcast-mode", "async", "--fees", "100ukex", "--yes"}
default:
log.Error("Unsupported transaction command", zap.String("command", cmd))
return "", fmt.Errorf("unsupported action: %s", cmd)
}

_, err = cm.ExecInContainer(ctx, containerID, command)
if err != nil {
log.Error("Failed to execute transaction command", zap.String("command", cmd), zap.Error(err))
return "", fmt.Errorf("failed to execute transaction command: %w", err)
}

log.Info("Transaction command executed successfully", zap.String("command", cmd))
return "Transaction executed successfully", nil
}

// handleJoinCommand processes the "join" command
func handleJoinCommand(args map[string]interface{}) (string, error) {
Expand Down
49 changes: 28 additions & 21 deletions src/shidai/internal/http_executor/http_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strconv"
"time"

"github.com/kiracore/sekin/src/shidai/internal/logger"
"github.com/kiracore/sekin/src/shidai/internal/utils"
"go.uber.org/zap"
)
Expand All @@ -19,76 +20,82 @@ type CommandRequest struct {
Args interface{} `json:"args"`
}

// Executes command for iCaller and sCaller
var log *zap.Logger = logger.GetLogger()

// ExecuteCallerCommand executes a command for iCaller and sCaller
func ExecuteCallerCommand(address, port, method string, commandRequest CommandRequest) ([]byte, error) {
log.Debug("Starting ExecuteCallerCommand", zap.String("address", address), zap.String("port", port), zap.String("method", method))

p, err := strconv.Atoi(port)
if err != nil {
return nil, fmt.Errorf("<%v> port is not valid", port)
log.Error("Invalid port conversion", zap.String("port", port), zap.Error(err))
return nil, fmt.Errorf("port conversion error for value: <%v>", port)
}
check := utils.ValidatePort(p)
if !check {
return nil, fmt.Errorf("<%v> port is not valid", port)
if !utils.ValidatePort(p) {
log.Error("Port validation failed", zap.String("port", port), zap.Int("parsedPort", p))
return nil, fmt.Errorf("port validation failed for value: <%v>", port)
}
// Convert your struct to JSON

jsonData, err := json.Marshal(commandRequest)
if err != nil {
zap.L().Debug("Error marshaling JSON:", zap.Error(err))
log.Error("Error marshaling JSON", zap.Error(err))
return nil, err
}
log.Debug("JSON data marshaled successfully")

// Create a new request
req, err := http.NewRequest(method, fmt.Sprintf("http://%v:%v/api/execute", address, port), bytes.NewBuffer(jsonData))
if err != nil {
zap.L().Debug("Error creating request:", zap.Error(err))
log.Error("Error creating HTTP request", zap.String("method", method), zap.String("URL", fmt.Sprintf("http://%v:%v/api/execute", address, port)), zap.Error(err))
return nil, err
}

// Set the content type to application/json
req.Header.Set("Content-Type", "application/json")
log.Debug("HTTP request created successfully", zap.String("url", req.URL.String()))

// Perform the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
zap.L().Debug("Error making request:", zap.Error(err))
log.Error("Error making HTTP request", zap.String("URL", req.URL.String()), zap.Error(err))
return nil, err
}
defer resp.Body.Close()
log.Debug("HTTP request executed", zap.Int("status_code", resp.StatusCode))

// Read and print the response body
body, err := io.ReadAll(resp.Body)
if err != nil {
zap.L().Debug("Error reading response body:", zap.Error(err))
log.Error("Error reading response body", zap.Error(err))
return nil, err
}
log.Debug("Response body read successfully", zap.ByteString("response", body))

// fmt.Println("Response:", string(body))
return body, nil
}

func DoHttpQuery(ctx context.Context, client *http.Client, url, method string) ([]byte, error) {
const timeoutQuery = time.Second * 10
ctx, cancel := context.WithTimeout(ctx, timeoutQuery)
log.Debug("Starting DoHttpQuery", zap.String("url", url), zap.String("method", method))
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()

req, err := http.NewRequestWithContext(ctx, method, url, nil)
if err != nil {
zap.L().Debug("ERROR: Failed to create request:", zap.Error(err))
log.Error("Failed to create HTTP request with context", zap.Error(err))
return nil, err
}
log.Debug("HTTP request with context created successfully", zap.String("url", req.URL.String()))

resp, err := client.Do(req)
if err != nil {
zap.L().Debug("ERROR: Failed to send request: %s", zap.Error(err))
log.Error("Failed to send HTTP request", zap.Error(err))
return nil, err
}
defer resp.Body.Close()
log.Debug("HTTP request sent successfully", zap.Int("status_code", resp.StatusCode))

body, err := io.ReadAll(resp.Body)
if err != nil {
zap.L().Debug("ERROR: Failed to read response body: %s", zap.Error(err))
log.Error("Failed to read response body", zap.Error(err))
return nil, err
}
log.Debug("Response body read successfully", zap.ByteString("response", body))

return body, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,63 +95,64 @@ func FormSekaiJoinerConfigs(tc *TargetSeedKiraConfig) error {
}
return nil
}

func retrieveNetworkInformation(ctx context.Context, tc *TargetSeedKiraConfig) (*networkInfo, error) {
log.Info("Retrieving Sekai network information", zap.String("IP", tc.IpAddress), zap.String("port", tc.SekaidRPCPort))
statusResponse, err := sekaihelper.GetSekaidStatus(ctx, tc.IpAddress, tc.SekaidRPCPort)

if err != nil {
return nil, fmt.Errorf("getting sekaid status: %w", err)
log.Error("Failed to get Sekaid status", zap.Error(err))
return nil, fmt.Errorf("getting Sekaid status: %w", err)
}

// Parse all peers in the network
nodes, _, err := networkparser.GetAllNodesV3(ctx, tc.IpAddress, 3, false)
if err != nil {
log.Error("Failed to parse peers", zap.Error(err))
return nil, fmt.Errorf("unable to parse peers: %w", err)
}

var mu sync.Mutex
var wg sync.WaitGroup
var listOfSeeds []string

// Process each node to retrieve and parse public P2P list
for _, node := range nodes {
wg.Add(1)
go func(n networkparser.Node) {
defer wg.Done()
pupP2PListResponse, err := getPubP2PList(ctx, n.IP, "11000")
if err != nil {
zap.L().Debug("getting sekaid public P2P list:", zap.Error(err))
log.Debug("Failed to get public P2P list", zap.String("IP", n.IP), zap.Error(err))
return
}
local, err := parsePubP2PListResponse(pupP2PListResponse)
if err != nil {
zap.L().Debug("parsing sekaid public P2P list", zap.Error(err))
log.Debug("Failed to parse public P2P list response", zap.String("IP", n.IP), zap.Error(err))
return
}

// Synchronize the addition of new seeds
mu.Lock()
for _, s := range local {
exist := false
for _, ss := range listOfSeeds {
if s == ss {
exist = true
// zap.L().Debug("already exist", zap.String("IP", ss))
log.Info("already exist", zap.String("IP", ss))
break
}
}
if !exist {
zap.L().Debug("adding peer", zap.String("IP", s))
if !utils.ContainsValue(listOfSeeds, s) {
log.Debug("Adding new seed", zap.String("IP", s))
listOfSeeds = append(listOfSeeds, s)
} else {
log.Info("Seed already exists", zap.String("IP", s))
}
}
mu.Unlock()
}(node)

}
wg.Wait()

// Handle case where no seeds are found
if len(listOfSeeds) == 0 {
zap.L().Debug("ERROR: List of seeds is empty, the trusted seed will be used")
log.Warn("No seeds found; using trusted seed", zap.String("nodeID", statusResponse.Result.NodeInfo.ID), zap.String("IP", tc.IpAddress), zap.String("P2PPort", tc.SekaidP2PPort))
listOfSeeds = []string{fmt.Sprintf("tcp://%s@%s:%s", statusResponse.Result.NodeInfo.ID, tc.IpAddress, tc.SekaidP2PPort)}
}
zap.L().Debug("LIST OF seeds ==================================== ", zap.Strings("listOfSeeds", listOfSeeds))

log.Info("Completed retrieval of network information", zap.Strings("listOfSeeds", listOfSeeds))
return &networkInfo{
NetworkName: statusResponse.Result.NodeInfo.Network,
NodeID: statusResponse.Result.NodeInfo.ID,
Expand Down
Loading

0 comments on commit b9d6d00

Please sign in to comment.