Skip to content

Commit

Permalink
feat: integrate polkadot package in dive-cli for local network setup
Browse files Browse the repository at this point in the history
  • Loading branch information
abhiyana committed Dec 13, 2023
1 parent ebd9f9e commit 9f77046
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 21 deletions.
2 changes: 2 additions & 0 deletions cli/cmd/chains/chains.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/hugobyte/dive-core/cli/cmd/chains/hardhat"
"github.com/hugobyte/dive-core/cli/cmd/chains/icon"
"github.com/hugobyte/dive-core/cli/cmd/chains/neutron"
"github.com/hugobyte/dive-core/cli/cmd/chains/polkadot"
"github.com/hugobyte/dive-core/cli/common"
"github.com/spf13/cobra"
)
Expand All @@ -26,6 +27,7 @@ maintenance within the specified blockchain ecosystem.`,
AddCommand(hardhat.HardhatCmd).
AddCommand(archway.ArchwayCmd).
AddCommand(neutron.NeutronCmd).
AddCommand(polkadot.PolkadotCmd).
SetRun(chains).
Build()

Expand Down
68 changes: 68 additions & 0 deletions cli/cmd/chains/polkadot/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package polkadot

import (
"fmt"

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

var (
configFilePath string
paraChain string
network string
paraNodes string
relayNodes string
explorer bool
metrics bool
)

const (
runPolkadotFunctionName = "run"
runPolkadotRelayLocal = "start_relay_chains_local"
runPolkadotRelayTestnetMainet = "start_test_main_net_relay_nodes"
)

var PolkadotCmd = common.NewDiveCommandBuilder().
SetUse("polkadot").
SetShort("Build, initialize and start a polkadot node").
SetLong("The command starts the polkadot relay chain and polkadot parachain if -p flag is given").
SetRun(polkadot).
AddStringFlagWithShortHand(&paraChain, "parachain", "p", "", "specify the parachain to spwan parachain node").
AddStringFlagWithShortHand(&network, "network", "n", "", "specify the which network to run. local/testnet/mainnet. default will be local.").
AddStringFlag(&paraNodes, "para-nodes", "", "specify the nodes for parachain, default will be '[full, collator]'").
AddStringFlag(&relayNodes, "relay-nodes", "", "specify the nodes for relaychain, default will be '[full, validator]'").
AddStringFlagWithShortHand(&configFilePath, "config", "c", "", "path to custom config json file to stat polakdot relaychain and parachain nodes.").
AddBoolFlag(&explorer, "explorer", false, "specify the bool flag if you wanna start polakdot js explorer service").
AddBoolFlag(&metrics, "metrics", false, "specify the bool flag if you wanna start prometheus metrics service").
Build()

func polkadot(cmd *cobra.Command, args []string) {
cliContext := common.GetCliWithKurtosisContext()

err := common.ValidateArgs(args)

if err != nil {
cliContext.Fatalf("Error %s. %s", err, cmd.UsageString())
}

cliContext.StartSpinnerIfNotVerbose("Starting Polkadot Node", common.DiveLogs)

response, err := RunPolkadot(cliContext)

if err != nil {
cliContext.Fatal(err)
}
serviceFileName := fmt.Sprintf(common.ServiceFilePath, common.EnclaveName)

fmt.Print(response.Dive)
for serviceName := range response.Dive {
err = common.WriteServiceResponseData(response.Dive[serviceName].ServiceName, *response.Dive[serviceName], cliContext, serviceFileName)

if err != nil {
cliContext.Fatal(err)
}
}

cliContext.StartSpinnerIfNotVerbose("Polkadot Node Started. Please find the service details in current working directory(services.json)", common.DiveLogs)
}
126 changes: 126 additions & 0 deletions cli/cmd/chains/polkadot/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package polkadot

import (
"fmt"

"github.com/kurtosis-tech/kurtosis/api/golang/core/lib/enclaves"

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

const (
localChain = "local"
configsDirectory = "/Users/abhishekharde/Desktop/hugobyte/dive-packages/services/polkadot/parachain/static_files/configs"
)

func RunPolkadot(cli *common.Cli) (*common.DiveMultipleServiceResponse, error) {
enclaveContext, err := cli.Context().GetEnclaveContext(common.EnclaveName)

if err != nil {
return nil, common.WrapMessageToError(err, "Polkadot Run Failed")
}
var serviceConfig = &utils.PolkadotServiceConfig{}

err = common.LoadConfig(cli, serviceConfig, configFilePath)

if err != nil {
return nil, err
}

configureService(serviceConfig)

encodedServiceConfigDataString, err := serviceConfig.EncodeToString()

para := fmt.Sprintf("{args: %s}", encodedServiceConfigDataString)

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

runConfig := getPolkadotRunConfig(serviceConfig, enclaveContext, para)

response, _, err := enclaveContext.RunStarlarkPackage(cli.Context().GetContext(), common.PolkadotRemotePackagePath, runConfig)

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

responseData, services, skippedInstructions, err := common.GetSerializedData(cli, response)

if err != nil {

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

return nil, common.WrapMessageToError(err, "Polkadot Run Failed ")
}

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

polkadotResponseData := &common.DiveMultipleServiceResponse{}
result, err := polkadotResponseData.Decode([]byte(responseData))

fmt.Print(result)

if err != nil {

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

return nil, common.WrapMessageToErrorf(common.ErrDataUnMarshall, "%s.%s", err, "Polkadot Run Failed ")

}

return result, nil
}

func configureService(serviceConfig *utils.PolkadotServiceConfig) {
if paraChain != "" {
serviceConfig.Para[0].Name = paraChain
}

if network != "" {
serviceConfig.ChainType = network
if network == "testnet" {
serviceConfig.RelayChain.Name = "rococo"
} else if network == "mainnet" {
serviceConfig.RelayChain.Name = "polkadot"
}
}

if explorer {
serviceConfig.Explorer = true
}

if metrics {
configureMetrics(serviceConfig)
}
}

func configureMetrics(serviceConfig *utils.PolkadotServiceConfig) {
for _, node := range append(serviceConfig.RelayChain.Nodes, serviceConfig.Para[0].Nodes...) {
node.Prometheus = true
}
}

func getPolkadotRunConfig(serviceConfig *utils.PolkadotServiceConfig, enclaveContext *enclaves.EnclaveContext, para string) *starlark_run_config.StarlarkRunConfig {
if serviceConfig.Para[0].Name != "" {
return common.GetStarlarkRunConfig(para, common.DivePolkadotDefaultNodeSetupScript, runPolkadotFunctionName)
} else {
if serviceConfig.ChainType == localChain {
enclaveContext.UploadFiles(configsDirectory, "configs")
return common.GetStarlarkRunConfig(para, common.DivePolkadotRelayNodeSetupScript, runPolkadotRelayLocal)
} else {
return common.GetStarlarkRunConfig(para, common.DivePolkadotRelayNodeSetupScript, runPolkadotRelayTestnetMainet)
}

}
}
64 changes: 64 additions & 0 deletions cli/cmd/chains/utils/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,67 @@ func (sc *HardhatServiceConfig) EncodeToString() (string, error) {

return string(encodedBytes), nil
}

// This code is for polkadot config file

type NodeConfig struct {
Name string `json:"name"`
NodeType string `json:"node-type"`
Port int `json:"port"`
Prometheus bool `json:"prometheus"`
}

type RelayChainConfig struct {
Name string `json:"name"`
Nodes []NodeConfig `json:"nodes"`
}

type ParaNodeConfig struct {
Name string `json:"name"`
Nodes []NodeConfig `json:"nodes"`
}

type PolkadotServiceConfig struct {
ChainType string `json:"chain-type"`
RelayChain RelayChainConfig `json:"relaychain"`
Para []ParaNodeConfig `json:"para"`
Explorer bool `json:"explorer"`
}

func (sc *PolkadotServiceConfig) EncodeToString() (string, error) {
encodedBytes, err := json.Marshal(sc)
if err != nil {
return "", common.WrapMessageToError(common.ErrDataMarshall, err.Error())
}

return string(encodedBytes), nil
}

func (sc *PolkadotServiceConfig) LoadConfigFromFile(cliContext *common.Cli, filePath string) error {
err := cliContext.FileHandler().ReadJson(filePath, sc)
if err != nil {
return common.WrapMessageToError(err, "Failed To Load Configuration")
}
return nil
}

func (sc *PolkadotServiceConfig) LoadDefaultConfig() error {
sc.ChainType = "local"
sc.Explorer = false
sc.RelayChain.Name = "rococo-local"
sc.RelayChain.Nodes = []NodeConfig{
{Name: "bob", NodeType: "full", Port: 9944, Prometheus: false},
{Name: "alice", NodeType: "validator", Port: 9955, Prometheus: false},
}
sc.Para = []ParaNodeConfig{
{
Name: "",
Nodes: []NodeConfig{
{Name: "alice", NodeType: "full", Prometheus: false},
{Name: "bob", NodeType: "collator", Prometheus: false},
},
},
}

return nil
}
46 changes: 25 additions & 21 deletions cli/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,31 @@ package common
const DiveVersion = "v0.0.14-beta"

const (
DiveEnclave = "dive"
DiveRemotePackagePath = "github.com/hugobyte/dive-packages"
DiveIconNodeScript = "services/jvm/icon/src/node-setup/start_icon_node.star"
DiveIconDecentralizeScript = "services/jvm/icon/src/node-setup/setup_icon_node.star"
DiveEthHardhatNodeScript = "services/evm/eth/src/node-setup/start-eth-node.star"
DiveArchwayNodeScript = "services/cosmvm/archway/src/node-setup/start_node.star"
DiveCosmosDefaultNodeScript = "services/cosmvm/cosmos_chains.star"
DiveNeutronNodeScript = "services/cosmvm/neutron/src/node-setup/start_node.star"
RelayServiceNameIconToCosmos = "ibc-relayer"
DiveNeutronDefaultNodeScript = "services/cosmvm/neutron/neutron.star"
DiveBridgeBtpScript = "/services/bridges/btp/src/bridge.star"
DiveBridgeIbcScript = "/services/bridges/ibc/src/bridge.star"
DiveDryRun = false
DiveDefaultParallelism = 4
DiveLogDirectory = "/logs/"
DiveDitLogFile = "dive.log"
DiveErrorLogFile = "error.log"
DiveOutFile = "dive_%s.json"
ServiceFilePath = "services_%s.json"
DiveAppDir = ".dive"
removeServiceStarlarkScript = `
DiveEnclave = "dive"
DiveRemotePackagePath = "github.com/hugobyte/dive-packages"
DiveIconNodeScript = "services/jvm/icon/src/node-setup/start_icon_node.star"
DiveIconDecentralizeScript = "services/jvm/icon/src/node-setup/setup_icon_node.star"
DiveEthHardhatNodeScript = "services/evm/eth/src/node-setup/start-eth-node.star"
DiveArchwayNodeScript = "services/cosmvm/archway/src/node-setup/start_node.star"
DiveCosmosDefaultNodeScript = "services/cosmvm/cosmos_chains.star"
DiveNeutronNodeScript = "services/cosmvm/neutron/src/node-setup/start_node.star"
RelayServiceNameIconToCosmos = "ibc-relayer"
DiveNeutronDefaultNodeScript = "services/cosmvm/neutron/neutron.star"
DiveBridgeBtpScript = "/services/bridges/btp/src/bridge.star"
DiveBridgeIbcScript = "/services/bridges/ibc/src/bridge.star"
PolkadotRemotePackagePath = "/Users/abhishekharde/Desktop/hugobyte/polkadot-kurtosis-package/"
DivePolkadotDefaultNodeSetupScript = "main.star"
DivePolkadotRelayNodeSetupScript = "/relaychain/relay-chain.star"

DiveDryRun = false
DiveDefaultParallelism = 4
DiveLogDirectory = "/logs/"
DiveDitLogFile = "dive.log"
DiveErrorLogFile = "error.log"
DiveOutFile = "dive_%s.json"
ServiceFilePath = "services_%s.json"
DiveAppDir = ".dive"
removeServiceStarlarkScript = `
def run(plan,args):
plan.remove_service(name=args["service_name"])
`
Expand Down
13 changes: 13 additions & 0 deletions cli/common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ type DiveServiceResponse struct {
ChainKey string `json:"chain_key,omitempty"`
}

type DiveMultipleServiceResponse struct {
Dive map[string]*DiveServiceResponse
}

// The `Decode` function is a method of the `DiveServiceResponse` struct. It takes a byte slice
// `responseData` as input and attempts to decode it into a `DiveServiceResponse` object.
func (dive *DiveServiceResponse) Decode(responseData []byte) (*DiveServiceResponse, error) {
Expand All @@ -28,6 +32,15 @@ func (dive *DiveServiceResponse) Decode(responseData []byte) (*DiveServiceRespon
return dive, nil
}

func (dive *DiveMultipleServiceResponse) Decode(responseData []byte) (*DiveMultipleServiceResponse, error) {

err := json.Unmarshal(responseData, &dive.Dive)
if err != nil {
return nil, WrapMessageToError(ErrDataUnMarshall, err.Error())
}
return dive, nil
}

// The `EncodeToString` function is a method of the `DiveServiceResponse` struct. It encodes the
// `DiveServiceResponse` object into a JSON string representation.
func (dive *DiveServiceResponse) EncodeToString() (string, error) {
Expand Down

0 comments on commit 9f77046

Please sign in to comment.