Skip to content

Commit

Permalink
feat: update ibc command for starting ibc bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
shreyasbhat0 committed Dec 7, 2023
1 parent 2c57d2c commit 31290e0
Show file tree
Hide file tree
Showing 12 changed files with 333 additions and 24 deletions.
27 changes: 23 additions & 4 deletions cli/cmd/bridge/bridge.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package bridge

import (
"github.com/hugobyte/dive-core/cli/cmd/bridge/relays"
"os"
"slices"

"github.com/hugobyte/dive-core/cli/cmd/bridge/btp"
"github.com/hugobyte/dive-core/cli/cmd/bridge/ibc"
"github.com/hugobyte/dive-core/cli/common"
"github.com/spf13/cobra"
)
Expand All @@ -12,8 +16,23 @@ var BridgeCmd = common.NewDiveCommandBuilder().
SetLong(`To connect two different chains using any of the supported cross chain communication protocols.
This will create an relay to connect two different chains and pass any messages between them.`).
SetRun(bridge).
AddCommand(relays.BtpRelayCmd).
AddCommand(relays.IbcRelayCmd).
AddCommand(btp.BtpRelayCmd).
AddCommand(ibc.IbcRelayCmd).
Build()

func bridge(cmd *cobra.Command, args []string) {}
func bridge(cmd *cobra.Command, args []string) {
cli := common.GetCli()
validArgs := cmd.ValidArgs
for _, c := range cmd.Commands() {
validArgs = append(validArgs, c.Name())
}
cmd.ValidArgs = validArgs

if len(args) == 0 {
cmd.Help()

} else if !slices.Contains(cmd.ValidArgs, args[0]) {
cli.Error(common.WrapMessageToErrorf(common.ErrInvalidCommand, "%s", cmd.UsageString()))
os.Exit(1)
}
}
13 changes: 12 additions & 1 deletion cli/cmd/bridge/relays/btp.go → cli/cmd/bridge/btp/cmd.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
package relays
package btp

import (
"github.com/hugobyte/dive-core/cli/common"
"github.com/spf13/cobra"
)

const bridgeMainFunction = "run_btp_setup"
const runbridgeicon2icon = "start_btp_for_already_running_icon_nodes"
const runbridgeicon2ethhardhat = "start_btp_icon_to_eth_for_already_running_nodes"

var (
chainA string
chainB string
serviceA string
serviceB string
)

var BtpRelayCmd = common.NewDiveCommandBuilder().
SetUse("btp").
SetShort("Starts BTP Relay to bridge between ChainA and ChainB").
Expand Down
1 change: 1 addition & 0 deletions cli/cmd/bridge/btp/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package btp
52 changes: 52 additions & 0 deletions cli/cmd/bridge/ibc/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package ibc

import (
"fmt"

"github.com/hugobyte/dive-core/cli/common"
"github.com/spf13/cobra"
)

var (
chainA string
chainB string
serviceA string
serviceB string
)

var IbcRelayCmd = common.NewDiveCommandBuilder().
SetUse("ibc").
SetShort("Start connection between Cosmos based chainA and ChainB and initiate communication between them").
SetLong(`This Command deploy , initialize the contracts and make it ready for ibc.
Along with that setup and starts the ibc relayer to establish communication between chains specified`).
SetRun(ibcRelay).
AddStringFlag(&chainA, "chainA", "", "Mention Name of Supported Chain").
AddStringFlag(&chainB, "chainB", "", "Mention Name of Supported Chain").
AddStringFlag(&serviceA, "chainAServiceName", "", "Service Name of Chain A from services.json").
AddStringFlag(&serviceB, "chainBServiceName", "", "Service Name of Chain B from services.json").
MarkFlagRequired("chainA").
MarkFlagRequired("chainB").
Build()

func ibcRelay(cmd *cobra.Command, args []string) {

cliContext := common.GetCliWithKurtosisContext()

err := common.ValidateArgs(args)

if err != nil {
cliContext.Fatalf("Error %s. %s", err, cmd.UsageString())
}
cliContext.Spinner().StartWithMessage("Starting IBC Setup", "green")
result, err := RunIbcRelay(cliContext)
if err != nil {
cliContext.Fatal(err)
}

err = cliContext.FileHandler().WriteFile("dive.json", []byte(result))
if err != nil {
cliContext.Fatal(err)
}

cliContext.Spinner().StopWithMessage(fmt.Sprintf("IBC Setup Completed between %s and %s. Please find service details in current working directory(dive.json)", chainA, chainB))
}
130 changes: 130 additions & 0 deletions cli/cmd/bridge/ibc/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package ibc

import (
"fmt"

"github.com/hugobyte/dive-core/cli/cmd/bridge/utils"
"github.com/hugobyte/dive-core/cli/common"
"github.com/kurtosis-tech/kurtosis/api/golang/core/lib/enclaves"
)

func RunIbcRelay(cli *common.Cli) (string, error) {
var starlarkExecutionResponse string
chains := utils.InitChains(chainA, chainB, serviceA, serviceB, false)

err := chains.CheckForIbcSupportedChains()

if err != nil {

return "", common.WrapMessageToError(common.ErrInvalidChain, err.Error())
}

enclaveContext, err := cli.Context().GetEnclaveContext(common.DiveEnclave)
if err != nil {
return "", common.WrapMessageToError(err, "IBC Setup Failed")
}

if chains.CheckChainServiceNamesEmpty() {
srcChainServiceResponse, dstChainServiceResponse, err := chains.GetServicesResponse(cli)
if err != nil {
return "", err
}
starlarkExecutionResponse, err = setupIbcRelayforAlreadyRunningCosmosChain(cli, enclaveContext, chains.ChainA, chains.ChainB, srcChainServiceResponse, dstChainServiceResponse)

if err != nil {
return "", err
}

} else {
starlarkExecutionResponse, err = startCosmosChainsAndSetupIbcRelay(cli, enclaveContext, chains)
if err != nil {
return "", err
}
}

if chainA == "icon" {
_, err := startIbcRelayIconToCosmos(cli, enclaveContext, common.RelayServiceNameIconToCosmos)
if err != nil {
return "", err
}
}

return starlarkExecutionResponse, nil
}

func startIbcRelayIconToCosmos(cli *common.Cli, enclaveContext *enclaves.EnclaveContext, serviceName string) (string, error) {
params := fmt.Sprintf(`{"service_name": "%s"}`, serviceName)
starlarkConfig := common.GetStarlarkRunConfig(params, "services/bridges/ibc/src/bridge.star", "start_relay")
executionData, _, err := enclaveContext.RunStarlarkRemotePackage(cli.Context().GetContext(), common.DiveRemotePackagePath, starlarkConfig)

if err != nil {
return "", common.WrapMessageToError(common.ErrStarlarkRunFailed, err.Error())
}

executionSerializedData, services, _, err := common.GetSerializedData(cli, executionData)

if err != nil {
errRemove := cli.Context().RemoveServicesByServiceNames(services, common.DiveEnclave)
if errRemove != nil {
return "", common.WrapMessageToError(errRemove, "IBC Setup Run Failed")
}

return "", common.WrapMessageToError(err, "IBC Setup Run Failed")

}

return executionSerializedData, nil
}

func startCosmosChainsAndSetupIbcRelay(cli *common.Cli, enclaveCtx *enclaves.EnclaveContext, chains *utils.Chains) (string, error) {

params := chains.GetIbcRelayParams()

executionResult, err := runStarlarkPackage(cli, enclaveCtx, params, "run_cosmos_ibc_setup")

if err != nil {
return "", err
}

return executionResult, nil
}

func setupIbcRelayforAlreadyRunningCosmosChain(cli *common.Cli, enclaveCtx *enclaves.EnclaveContext, chainA, chainB, chainAServiceResponse, chainBServiceResponse string) (string, error) {

params := fmt.Sprintf(`{"src_chain":"%s","dst_chain":"%s", "src_chain_config":%s, "dst_chain_config":%s}`, chainA, chainB, chainAServiceResponse, chainBServiceResponse)

executionResult, err := runStarlarkPackage(cli, enclaveCtx, params, "run_cosmos_ibc_relay_for_already_running_chains")

if err != nil {
return "", err
}

return executionResult, nil
}

func runStarlarkPackage(cli *common.Cli, enclaveContext *enclaves.EnclaveContext, params, functionName string) (string, error) {
starlarkConfig := common.GetStarlarkRunConfig(params, common.DiveBridgeIbcScript, functionName)
executionData, _, err := enclaveContext.RunStarlarkRemotePackage(cli.Context().GetContext(), common.DiveRemotePackagePath, starlarkConfig)

if err != nil {
return "", err
}

executionSerializedData, services, skippedInstructions, err := common.GetSerializedData(cli, executionData)

if err != nil {
errRemove := cli.Context().RemoveServicesByServiceNames(services, common.DiveEnclave)
if errRemove != nil {
return "", common.WrapMessageToError(errRemove, "IBC Setup Run Failed")
}

return "", common.WrapMessageToError(err, "IBC Setup Run Failed")

}

if cli.Context().CheckSkippedInstructions(skippedInstructions) {
return "", common.WrapMessageToError(common.ErrStarlarkResponse, "Already Running")
}

return executionSerializedData, nil
}
1 change: 0 additions & 1 deletion cli/cmd/bridge/relays/common.go

This file was deleted.

16 changes: 0 additions & 16 deletions cli/cmd/bridge/relays/ibc.go

This file was deleted.

108 changes: 108 additions & 0 deletions cli/cmd/bridge/utils/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package utils

import (
"fmt"
"slices"
"strconv"
"strings"

"github.com/hugobyte/dive-core/cli/common"
)

const (
IconChain = "icon"
EthChain = "eth"
HardhatChain = "hardhat"
ArchwayChain = "archway"
NeutronChain = "neutron"
)

var supportedChainsForBtp = []string{IconChain, EthChain, HardhatChain}
var supportedChainsForIbc = []string{ArchwayChain, NeutronChain, IconChain}

type Chains struct {
ChainA string
ChainB string
ChainAServiceName string
ChainBServiceName string
Bridge string
}

func InitChains(chainA, chainB, serviceA, serviceB string, bridge bool) *Chains {
return &Chains{

ChainA: strings.ToLower(chainA),
ChainB: strings.ToLower(chainB),
ChainAServiceName: serviceA,
ChainBServiceName: serviceB,
Bridge: strconv.FormatBool(bridge),
}
}

func (c *Chains) AreChainsIcon() bool {
return (c.ChainA == "icon" && c.ChainB == "icon")
}

func (chains *Chains) GetParams() string {
return fmt.Sprintf(`{"src_chain": "%s", "dst_chain": "%s", "bridge":"%s"}`, chains.ChainA, chains.ChainB, chains.Bridge)
}
func (chains *Chains) GetIbcRelayParams() string {

return fmt.Sprintf(`{"src_chain": "%s", "dst_chain": "%s"}`, chains.ChainA, chains.ChainB)
}

func (chains *Chains) GetServicesResponse(cli *common.Cli) (string, string, error) {

var serviceConfig = common.Services{}

err := cli.FileHandler().ReadJson("services.json", &serviceConfig)

if err != nil {
return "", "", err
}

chainAServiceResponse, OK := serviceConfig[chains.ChainAServiceName]
if !OK {
return "", "", fmt.Errorf("service name not found")
}
chainBServiceResponse, OK := serviceConfig[chains.ChainBServiceName]
if !OK {
return "", "", fmt.Errorf("service name not found")
}

srcChainServiceResponse, err := chainAServiceResponse.EncodeToString()
if err != nil {
return "", "", err
}
dstChainServiceResponse, err := chainBServiceResponse.EncodeToString()

if err != nil {
return "", "", err
}

return srcChainServiceResponse, dstChainServiceResponse, nil
}

func (chains *Chains) CheckForBtpSupportedChains() error {
if !slices.Contains(supportedChainsForBtp, chains.ChainA) {
return fmt.Errorf("invalid Chain: %s", chains.ChainA)
}
if !slices.Contains(supportedChainsForBtp, chains.ChainB) {
return fmt.Errorf("invalid Chain: %s", chains.ChainB)
}
return nil
}

func (chains *Chains) CheckForIbcSupportedChains() error {
if !slices.Contains(supportedChainsForIbc, chains.ChainA) {
return fmt.Errorf("invalid Chain: %s", chains.ChainA)
}
if !slices.Contains(supportedChainsForIbc, chains.ChainB) {
return fmt.Errorf("invalid Chain: %s", chains.ChainB)
}
return nil
}

func (chains *Chains) CheckChainServiceNamesEmpty() bool {
return (chains.ChainAServiceName != "" && chains.ChainBServiceName != "")
}
4 changes: 3 additions & 1 deletion cli/common/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,10 @@ func (c *Cli) Fatalf(format string, err error, args ...interface{}) {

func (c *Cli) Error(err error) {
c.spinner.Stop()

c.log.SetErrorToStderr()
c.log.Error(CodeOf(err), err.Error())
actualError, _ := CoderOf(err)
c.log.Error(actualError.ErrorCode(), fmt.Sprintf("%s. message: %s", actualError.Error(), err.Error()))
}

func (c *Cli) Fatal(err error) {
Expand Down
1 change: 1 addition & 0 deletions cli/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,5 @@ const (
InvalidPathError
InvalidFileError
KurtosisServiceError
InvalidChain
)
Loading

0 comments on commit 31290e0

Please sign in to comment.