diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index f65fb375..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,32 +0,0 @@ -version: 2.1 - -executors: - ubuntu_vm: - machine: - image: ubuntu-2004:202201-02 - -jobs: - run_starlark: - executor: ubuntu_vm - steps: - - # Set up Kurtosis - - run: | - echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list - sudo apt update - sudo apt install kurtosis-cli - - - checkout - - - run: | - # TODO parameterize this as necessary - kurtosis run . - -workflows: - build: - jobs: - # -- PR check jobs ------------------------------------------ - - run_starlark: - filters: - branches: - ignore: diff --git a/cli/commands/bridge/bridge.go b/cli/commands/bridge/bridge.go index 1167a7b3..cae630fd 100644 --- a/cli/commands/bridge/bridge.go +++ b/cli/commands/bridge/bridge.go @@ -7,7 +7,7 @@ import ( "fmt" "os" - "github.com/hugobyte/dive/cli/commands/bridge/relyas" + "github.com/hugobyte/dive/cli/commands/bridge/relays" "github.com/hugobyte/dive/cli/common" "github.com/spf13/cobra" "golang.org/x/exp/slices" @@ -30,7 +30,7 @@ This will create an relay to connect two different chains and pass any messages if len(args) == 0 { cmd.Help() - + } else if !slices.Contains(cmd.ValidArgs, args[0]) { diveContext.Log.SetOutput(os.Stderr) @@ -42,9 +42,9 @@ This will create an relay to connect two different chains and pass any messages }, } - bridgeCmd.AddCommand(relyas.BtpRelayCmd(diveContext)) + bridgeCmd.AddCommand(relays.BtpRelayCmd(diveContext)) - bridgeCmd.AddCommand(relyas.IbcRelayCmd(diveContext)) + bridgeCmd.AddCommand(relays.IbcRelayCmd(diveContext)) return bridgeCmd } diff --git a/cli/commands/bridge/relyas/btp.go b/cli/commands/bridge/relays/btp.go similarity index 99% rename from cli/commands/bridge/relyas/btp.go rename to cli/commands/bridge/relays/btp.go index 200d42bb..58c512fa 100644 --- a/cli/commands/bridge/relyas/btp.go +++ b/cli/commands/bridge/relays/btp.go @@ -1,4 +1,4 @@ -package relyas +package relays import ( "fmt" @@ -64,7 +64,7 @@ func BtpRelayCmd(diveContext *common.DiveContext) *cobra.Command { chains := initChains(chainA, chainB, serviceA, serviceB, bridge) if err := chains.checkForBtpSupportedChains(); err != nil { - diveContext.FatalError(err.Error(), fmt.Sprintf("Supported Chains for BTP: %v", suppottedChainsForBtp)) + diveContext.FatalError(err.Error(), fmt.Sprintf("Supported Chains for BTP: %v", supportedChainsForBtp)) } diveContext.StartSpinner(fmt.Sprintf(" Starting BTP Bridge for %s,%s", chains.chainA, chains.chainB)) diff --git a/cli/commands/bridge/relyas/common.go b/cli/commands/bridge/relays/common.go similarity index 86% rename from cli/commands/bridge/relyas/common.go rename to cli/commands/bridge/relays/common.go index 196892a4..0d33d7f1 100644 --- a/cli/commands/bridge/relyas/common.go +++ b/cli/commands/bridge/relays/common.go @@ -1,4 +1,4 @@ -package relyas +package relays import ( "fmt" @@ -10,8 +10,8 @@ import ( "github.com/hugobyte/dive/cli/common" ) -var suppottedChainsForBtp = []string{"icon", "eth", "hardhat"} -var supportedChainsForIbc = []string{"archway", "icon"} +var supportedChainsForBtp = []string{"icon", "eth", "hardhat"} +var supportedChainsForIbc = []string{"archway", "neutron", "icon"} type Chains struct { chainA string @@ -40,7 +40,7 @@ func (chains *Chains) getParams() string { } func (chains *Chains) getIbcRelayParams() string { - return fmt.Sprintf(`{"args":{"links": {"src": "%s", "dst": "%s"}}}`, chains.chainA, chains.chainB) + return fmt.Sprintf(`{"args":{"links": {"src": "%s", "dst": "%s"}, "src_config":{"data":{}}, "dst_config":{"data":{}}}}`, chains.chainA, chains.chainB) } func (chains *Chains) getServicesResponse() (string, string, error) { @@ -74,10 +74,10 @@ func (chains *Chains) getServicesResponse() (string, string, error) { } func (chains *Chains) checkForBtpSupportedChains() error { - if !slices.Contains(suppottedChainsForBtp, chains.chainA) { + if !slices.Contains(supportedChainsForBtp, chains.chainA) { return fmt.Errorf("invalid Chain: %s", chains.chainA) } - if !slices.Contains(suppottedChainsForBtp, chains.chainB) { + if !slices.Contains(supportedChainsForBtp, chains.chainB) { return fmt.Errorf("invalid Chain: %s", chains.chainB) } return nil diff --git a/cli/commands/bridge/relyas/ibc.go b/cli/commands/bridge/relays/ibc.go similarity index 99% rename from cli/commands/bridge/relyas/ibc.go rename to cli/commands/bridge/relays/ibc.go index 06c9595d..fbf8c23d 100644 --- a/cli/commands/bridge/relyas/ibc.go +++ b/cli/commands/bridge/relays/ibc.go @@ -1,4 +1,4 @@ -package relyas +package relays import ( "fmt" diff --git a/cli/commands/chain/types/neutron.go b/cli/commands/chain/types/neutron.go index 2ee95d97..0c8af0b5 100644 --- a/cli/commands/chain/types/neutron.go +++ b/cli/commands/chain/types/neutron.go @@ -2,6 +2,7 @@ package types import ( "encoding/json" + "fmt" "github.com/hugobyte/dive/cli/common" "github.com/kurtosis-tech/kurtosis/api/golang/core/kurtosis_core_rpc_api_bindings" @@ -9,13 +10,53 @@ import ( "github.com/spf13/cobra" ) +// Constants for function names const ( runNeutronNodeWithDefaultConfigFunctionName = "start_node_service" + runNeutronNodeWithCustomServiceFunctionName = "start_neutron_node" + construcNeutrontServiceConfigFunctionName = "get_service_config" ) +// Variable to store the Neutron node configuration file path +var ( + neutron_node_config string +) -func NewNeutronCmd(diveContext *common.DiveContext) *cobra.Command { +// NeutronServiceConfig stores configuration parameters for the Neutron service. +type NeutronServiceConfig struct { + ChainID string `json:"chainId"` + Key string `json:"key"` + Password string `json:"password"` + PublicGrpc int `json:"public_grpc"` + PublicTCP int `json:"public_tcp"` + PublicHTTP int `json:"public_http"` + PublicRPC int `json:"public_rpc"` +} +// EncodeToString encodes the NeutronServiceConfig struct to a JSON string. +func (as *NeutronServiceConfig) EncodeToString() (string, error) { + data, err := json.Marshal(as) + if err != nil { + return "", err + } + return string(data), nil +} + +// ReadServiceConfig reads the Neutron service configuration from a JSON file. +func (as *NeutronServiceConfig) ReadServiceConfig(path string) error { + configData, err := common.ReadConfigFile(neutron_node_config) + if err != nil { + return err + } + err = json.Unmarshal(configData, as) + if err != nil { + return err + } + return nil +} + +// NewNeutronCmd creates a new Cobra command for the Neutron service. +func NewNeutronCmd(diveContext *common.DiveContext) *cobra.Command { neutronCmd := &cobra.Command{ Use: "neutron", Short: "Build, initialize and start a neutron node", @@ -23,63 +64,73 @@ func NewNeutronCmd(diveContext *common.DiveContext) *cobra.Command { Run: func(cmd *cobra.Command, args []string) { common.ValidateCmdArgs(diveContext, args, cmd.UsageString()) runResponse := RunNeutronNode(diveContext) - common.WriteToServiceFile(runResponse.ServiceName, *runResponse) - diveContext.StopSpinner("Neutron Node Started. Please find service details in current working directory(services.json)") }, } - neutronCmd.Flags().StringVarP(&config, "config", "c", "", "path to custom config json file to start neutron node ") - + neutronCmd.Flags().StringVarP(&neutron_node_config, "config", "c", "", "path to custom config json file to start neutron node ") return neutronCmd } - +// RunNeutronNode starts the Neutron node. func RunNeutronNode(diveContext *common.DiveContext) *common.DiveserviceResponse { diveContext.InitKurtosisContext() kurtosisEnclaveContext, err := diveContext.GetEnclaveContext() - if err != nil { - diveContext.FatalError("Failed To Retrive Enclave Context", err.Error()) + diveContext.FatalError("Failed To Retrieve Enclave Context", err.Error()) } - diveContext.StartSpinner(" Starting Neutron Node") + diveContext.StartSpinner("Starting Neutron Node") + var serviceConfig = &NeutronServiceConfig{} var neutronResponse = &common.DiveserviceResponse{} var starlarkExecutionData = "" - starlarkExecutionData, err = runNeutronWithDefaultServiceConfig(diveContext, kurtosisEnclaveContext) - if err != nil { - diveContext.FatalError("Starlark Run Failed", err.Error()) + + if neutron_node_config != "" { + err := serviceConfig.ReadServiceConfig(neutron_node_config) + if err != nil { + diveContext.FatalError("Failed read service config", err.Error()) + } + + encodedServiceConfigDataString, err := serviceConfig.EncodeToString() + if err != nil { + diveContext.FatalError("Failed to encode service config", err.Error()) + } + + // Run Neutron Node with custom service config + starlarkExecutionData, err = RunNeutronWithServiceConfig(diveContext, kurtosisEnclaveContext, encodedServiceConfigDataString) + if err != nil { + diveContext.FatalError("Starlark Run Failed", err.Error()) + } + } else { + // Run Neutron Node with default service config + starlarkExecutionData, err = RunNeutronWithServiceConfig(diveContext, kurtosisEnclaveContext, "{}") + if err != nil { + diveContext.FatalError("Starlark Run Failed", err.Error()) + } } - err = json.Unmarshal([]byte(starlarkExecutionData), neutronResponse) + err = json.Unmarshal([]byte(starlarkExecutionData), neutronResponse) if err != nil { - diveContext.FatalError("Failed to Unmarshall Service Response", err.Error()) + diveContext.FatalError("Failed to Unmarshal Service Response", err.Error()) } return neutronResponse - } - -func runNeutronWithDefaultServiceConfig(diveContext *common.DiveContext, enclaveContext *enclaves.EnclaveContext) (string, error) { - - params := `{"args":{"data":{}}}` - nodeServiceResponse, _, err := enclaveContext.RunStarlarkRemotePackage(diveContext.Ctx, common.DiveRemotePackagePath, common.DiveNeutronDefaultNodeScript, runNeutronNodeWithDefaultConfigFunctionName, params, common.DiveDryRun, common.DiveDefaultParallelism, []kurtosis_core_rpc_api_bindings.KurtosisFeatureFlag{}) - +// RunNeutronWithServiceConfig runs the Neutron service with the provided configuration data. +func RunNeutronWithServiceConfig(diveContext *common.DiveContext, enclaveContext *enclaves.EnclaveContext, data string) (string, error) { + params := fmt.Sprintf(`{"args":{"data":%s}}`, data) + nodeServiceResponse, _, err := enclaveContext.RunStarlarkPackage(diveContext.Ctx, common.DiveRemotePackagePath, common.DiveNeutronDefaultNodeScript, runNeutronNodeWithDefaultConfigFunctionName, params, common.DiveDryRun, common.DiveDefaultParallelism, []kurtosis_core_rpc_api_bindings.KurtosisFeatureFlag{}) if err != nil { - return "", err - } nodeServiceResponseData, services, skippedInstructions, err := diveContext.GetSerializedData(nodeServiceResponse) if err != nil { - diveContext.StopServices(services) diveContext.FatalError("Starlark Run Failed", err.Error()) - } - diveContext.CheckInstructionSkipped(skippedInstructions, "Nueutron Node Already Running") + diveContext.CheckInstructionSkipped(skippedInstructions, "Neutron Node Already Running") return nodeServiceResponseData, nil -} \ No newline at end of file +} diff --git a/main.star b/main.star index ae9a4571..0d1f0010 100644 --- a/main.star +++ b/main.star @@ -244,12 +244,11 @@ def run_cosmos_ibc_setup(plan, args): source_chain = links["src"] destination_chain = links["dst"] - if source_chain == "archway" and destination_chain == "archway": - data = cosmvm_node.start_ibc_between_cosmvm_chains(plan,source_chain,destination_chain) - - config_data = run_cosmos_ibc_relay_for_already_running_chains(plan,links,data.src_config,data.dst_config) + if (source_chain in ["archway", "neutron"]) and (destination_chain in ["archway", "neutron"]): + data = cosmvm_node.start_ibc_between_cosmvm_chains(plan, source_chain, destination_chain, args) + config_data = run_cosmos_ibc_relay_for_already_running_chains(plan, links, data.src_config, data.dst_config, args) return config_data - + if destination_chain == "archway": src_chain_config = icon_service.start_node_service(plan) @@ -334,7 +333,7 @@ def run_cosmos_ibc_setup(plan, args): -def run_cosmos_ibc_relay_for_already_running_chains(plan,links,src_config,dst_config): +def run_cosmos_ibc_relay_for_already_running_chains(plan,links,src_config,dst_config, args): src_chain_service_name = src_config["service_name"] dst_chain_service_name = dst_config["service_name"] @@ -346,7 +345,7 @@ def run_cosmos_ibc_relay_for_already_running_chains(plan,links,src_config,dst_co config_data = input_parser.generate_new_config_data_cosmvm_cosmvm(links, src_chain_service_name, dst_chain_service_name) config_data["chains"][src_chain_service_name] = src_config config_data["chains"][dst_chain_service_name] = dst_config - cosmvm_relay.start_cosmos_relay(plan, src_chain_key, src_chain_id, dst_chain_key, dst_chain_id, src_config, dst_config) + cosmvm_relay.start_cosmos_relay(plan, src_chain_key, src_chain_id, dst_chain_key, dst_chain_id, src_config, dst_config, args) return config_data \ No newline at end of file diff --git a/package_io/constants.star b/package_io/constants.star index 6c09af9d..f7809712 100644 --- a/package_io/constants.star +++ b/package_io/constants.star @@ -53,11 +53,15 @@ ARCHWAY_SERVICE_CONFIG = struct( NEUTRON_SERVICE_CONFIG = struct( service_name = "neutron-node", - image = "hugobyte/neutron-node:v0.2" + image = "hugobyte/neutron-node:v0.2", + init_script = "github.com/hugobyte/dive/services/cosmvm/neutron/static_files/init.sh", + start_script = "github.com/hugobyte/dive/services/cosmvm/neutron/static_files/start.sh", + init_nutrond_script = "github.com/hugobyte/dive/services/cosmvm/neutron/static_files/init-neutrond.sh", + path = "/start-scripts/", ) IBC_RELAYER_SERVICE = struct( - ibc_relay_config_file_template = "github.com/hugobyte/dive/services/bridges/ibc/static-files/config/archwayjson.tpl", + ibc_relay_config_file_template = "github.com/hugobyte/dive/services/bridges/ibc/static-files/config/cosmosjson.tpl", relay_service_name = "cosmos-ibc-relay", # updated the ibc relay image relay_service_image = "hugobyte/ibc-relay:v0.1", @@ -94,7 +98,7 @@ ARCHAY_NODE1_CONFIG = struct( chain_id = "archway-node-1", grpc = 9080, http = 9092, - tcp = 26658, + tcp = 26659, rpc = 4566, key = "archway-node-1-key", ) @@ -113,9 +117,22 @@ NEUTRON_PRIVATE_PORTS = struct( grpc = 9090, ) -NEUTRON_PUBLIC_PORTS = struct( +NEUTRON_NODE1_CONFIG = struct( http = 1317, - rpc = 26659, + rpc = 26669, tcp = 26656, grpc = 8090, -) \ No newline at end of file + chain_id = "test-chain1", + key = "test-key", + password = "clock post desk civil pottery foster expand merit dash seminar song memory figure uniform spice circle try happy obvious trash crime hybrid hood cushion", +) + +NEUTRON_NODE2_CONFIG = struct( + http = 1311, + rpc = 26653, + tcp = 26652, + grpc = 8091, + chain_id = "test-chain2", + key = "test-key", + password = "clock post desk civil pottery foster expand merit dash seminar song memory figure uniform spice circle try happy obvious trash crime hybrid hood cushion", +) diff --git a/package_io/input_parser.star b/package_io/input_parser.star index 9c614aaf..63812b90 100644 --- a/package_io/input_parser.star +++ b/package_io/input_parser.star @@ -77,4 +77,9 @@ def generate_new_config_data_cosmvm_cosmvm(links, srcchain_service_name, dst_cha }, } - return config_data \ No newline at end of file + return config_data + + +def struct_to_dict(s): + fields = dir(s) + return {field: getattr(s, field) for field in fields if not field.startswith("_")} \ No newline at end of file diff --git a/services/bridges/ibc/src/bridge.star b/services/bridges/ibc/src/bridge.star index d39aa6c2..6f3a1350 100644 --- a/services/bridges/ibc/src/bridge.star +++ b/services/bridges/ibc/src/bridge.star @@ -1,65 +1,100 @@ +# Import required modules and constants constants = import_module("github.com/hugobyte/dive/package_io/constants.star") ibc_relay_config = constants.IBC_RELAYER_SERVICE -def start_cosmos_relay(plan, src_key, src_chain_id, dst_key, dst_chain_id, src_config, dst_config): - plan.print("starting cosmos relay") +def start_cosmos_relay(plan, src_key, src_chain_id, dst_key, dst_chain_id, src_config, dst_config, args): + """ + Start a Cosmos relay service with given source and destination chains configuration. + + Args: + plan (plan): plan. + src_key (str): The key for the source chain. + src_chain_id (str): The ID of the source chain. + dst_key (str): The key for the destination chain. + dst_chain_id (str): The ID of the destination chain. + src_config (dict): Configuration for the source chain. + dst_config (dict): Configuration for the destination chain. + args (dict): Additional arguments. + + Returns: + struct: Configuration information for the relay service. + """ + + plan.print("Starting Cosmos relay") + + plan.upload_files(src=ibc_relay_config.run_file_path, name="run") + + cosmos_config = read_file(ibc_relay_config.ibc_relay_config_file_template) - plan.upload_files(src = ibc_relay_config.run_file_path, name = "run") - comos_config = read_file(ibc_relay_config.ibc_relay_config_file_template) cfg_template_data = { "KEY": src_key, "CHAINID": src_chain_id, + "CHAIN": args["links"]["src"], } plan.render_templates( - config = { + config={ "cosmos-%s.json" % src_chain_id: struct( - template = comos_config, - data = cfg_template_data, + template=cosmos_config, + data=cfg_template_data, ), }, - name = "config-%s" % src_chain_id, + name="config-%s" % src_chain_id, ) cfg_template_data = { "KEY": dst_key, "CHAINID": dst_chain_id, + "CHAIN": args["links"]["dst"], } plan.render_templates( - config = { + config={ "cosmos-%s.json" % dst_chain_id: struct( - template = comos_config, - data = cfg_template_data, + template=cosmos_config, + data=cfg_template_data, ), }, - name = "config-%s" % dst_chain_id, + name="config-%s" % dst_chain_id, ) - plan.exec(service_name = src_config["service_name"], recipe = ExecRecipe(command = ["/bin/sh", "-c", "apk add jq"])) + # Install 'jq' based on the type of chain (neutron or archway) for the source + if args["links"]["src"] == "neutron": + plan.exec(service_name=src_config["service_name"], recipe=ExecRecipe(command=["/bin/sh", "-c", "apt install jq"])) + elif args["links"]["src"] == "archway": + plan.exec(service_name=src_config["service_name"], recipe=ExecRecipe(command=["/bin/sh", "-c", "apk add jq"])) - src_chain_seed = plan.exec(service_name = src_config["service_name"], recipe = ExecRecipe(command = ["/bin/sh", "-c", "jq -r '.mnemonic' ../../start-scripts/key_seed.json | tr -d '\n\r'"])) + # Retrieve the seed for the source chain + src_chain_seed = plan.exec(service_name=src_config["service_name"], recipe=ExecRecipe(command=["/bin/sh", "-c", "jq -r '.mnemonic' ../../start-scripts/key_seed.json | tr -d '\n\r'"])) - plan.exec(service_name = dst_config["service_name"], recipe = ExecRecipe(command = ["/bin/sh", "-c", "apk add jq"])) + # Install 'jq' based on the type of chain (neutron or archway) for the destination + if args["links"]["dst"] == "neutron": + plan.exec(service_name=dst_config["service_name"], recipe=ExecRecipe(command=["/bin/sh", "-c", "apt install jq"])) + elif args["links"]["src"] == "archway": + plan.exec(service_name=dst_config["service_name"], recipe=ExecRecipe(command=["/bin/sh", "-c", "apk add jq"])) - dst_chain_seed = plan.exec(service_name = dst_config["service_name"], recipe = ExecRecipe(command = ["/bin/sh", "-c", "jq -r '.mnemonic' ../../start-scripts/key_seed.json | tr -d '\n\r'"])) + # Retrieve the seed for the destination chain + dst_chain_seed = plan.exec(service_name=dst_config["service_name"], recipe=ExecRecipe(command=["/bin/sh", "-c", "jq -r '.mnemonic' ../../start-scripts/key_seed.json | tr -d '\n\r'"])) + # Configure the Cosmos relay service relay_service = ServiceConfig( - image = ibc_relay_config.relay_service_image, - files = { + image=ibc_relay_config.relay_service_image, + files={ ibc_relay_config.relay_config_files_path + src_chain_id: "config-%s" % src_chain_id, ibc_relay_config.relay_config_files_path + dst_chain_id: "config-%s" % dst_chain_id, ibc_relay_config.relay_config_files_path: "run", }, - entrypoint = ["/bin/sh", "-c", "chmod +x ../script/run.sh && sh ../script/run.sh '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s'" % (src_chain_id, dst_chain_id, src_key, dst_key, src_config["endpoint"], dst_config["endpoint"], src_chain_seed["output"], dst_chain_seed["output"])], + entrypoint=["/bin/sh", "-c", "chmod +x ../script/run.sh && sh ../script/run.sh '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s'" % (src_chain_id, dst_chain_id, src_key, dst_key, src_config["endpoint"], dst_config["endpoint"], src_chain_seed["output"], dst_chain_seed["output"])], ) plan.print(relay_service) - plan.add_service(name = ibc_relay_config.relay_service_name, config = relay_service) + plan.add_service(name=ibc_relay_config.relay_service_name, config=relay_service) return struct( - service_name = ibc_relay_config.relay_service_name, + service_name=ibc_relay_config.relay_service_name, ) + + def start_cosmos_relay_for_icon_to_cosmos(plan,src_chain_config,dst_chain_config): plan.print("starting the cosmos relay for icon to cosmos") diff --git a/services/bridges/ibc/static-files/config/cosmosjson.tpl b/services/bridges/ibc/static-files/config/cosmosjson.tpl new file mode 100644 index 00000000..6369b213 --- /dev/null +++ b/services/bridges/ibc/static-files/config/cosmosjson.tpl @@ -0,0 +1,17 @@ +{ +"type": "cosmos", +"value": { +"key": "{{.KEY}}", +"chain-id": "{{.CHAINID}}", +"rpc-addr": "", +"grpc-addr": "", +"account-prefix": "{{.CHAIN}}", +"keyring-backend": "test", +"gas-adjustment": 1.5, +"gas-prices": "0.0025stake", +"debug": true, +"timeout": "20s", +"output-format": "json", +"sign-mode": "direct" +} +} \ No newline at end of file diff --git a/services/cosmvm/archway/src/node-setup/deploy.star b/services/cosmvm/archway/src/node-setup/deploy.star index c6a1e6c1..8a5bdecc 100644 --- a/services/cosmvm/archway/src/node-setup/deploy.star +++ b/services/cosmvm/archway/src/node-setup/deploy.star @@ -1,9 +1,9 @@ -def deploy(plan, chain_id,chain_key, contract_name, message,service_name,password): +def deploy(plan, chain_id, chain_key, contract_name, message, service_name, password): contract = "../contracts/%s.wasm" % contract_name passcode = password - plan.exec(service_name = service_name, recipe = ExecRecipe(command = ["/bin/sh", "-c", "echo '%s' | archwayd tx wasm store %s --from %s --keyring-backend test --chain-id %s --gas auto --gas-adjustment 1.3 -y --output json -b block | jq -r '.logs[0].events[-1].attributes[1].value' > code_id.json " % (passcode, contract, chain_key,chain_id)])) + plan.exec(service_name = service_name, recipe = ExecRecipe(command = ["/bin/sh", "-c", "archwayd tx wasm store %s --from %s --keyring-backend test --chain-id %s --gas auto --gas-adjustment 1.3 -y --output json -b block | jq -r '.logs[0].events[-1].attributes[1].value' > code_id.json " % (contract, chain_key, chain_id)])) # Getting the code id @@ -13,10 +13,10 @@ def deploy(plan, chain_id,chain_key, contract_name, message,service_name,passwor plan.print("Instantiating the contract") - exec = ExecRecipe(command = ["/bin/sh", "-c", "echo '%s' | archwayd tx wasm instantiate %s '%s' --from %s --keyring-backend test --label %s --chain-id %s --no-admin --gas auto --gas-adjustment 1.3 -y -b block | tr -d '\n\r' " % (passcode, code_id["output"],message,chain_key,contract_name, chain_id)]) + exec = ExecRecipe(command = ["/bin/sh", "-c", "archwayd tx wasm instantiate %s '%s' --from %s --keyring-backend test --label %s --chain-id %s --no-admin --gas auto --gas-adjustment 1.3 -y -b block | tr -d '\n\r' " % (code_id["output"], message, chain_key, contract_name, chain_id)]) plan.exec(service_name = service_name, recipe = exec) # Getting the contract address - contract = plan.exec(service_name = service_name, recipe = ExecRecipe(command = ["/bin/sh", "-c", "echo %s | archwayd query wasm list-contract-by-code %s --output json | jq -r '.contracts[-1]' | tr -d '\n\r' " % (passcode, code_id["output"])])) + contract = plan.exec(service_name = service_name, recipe = ExecRecipe(command = ["/bin/sh", "-c", "archwayd query wasm list-contract-by-code %s --output json | jq -r '.contracts[-1]' | tr -d '\n\r' " % (code_id["output"])])) return contract["output"] diff --git a/services/cosmvm/cosmvm.star b/services/cosmvm/cosmvm.star index 9abc2111..bac6b8d9 100644 --- a/services/cosmvm/cosmvm.star +++ b/services/cosmvm/cosmvm.star @@ -1,5 +1,7 @@ archway_node_service = import_module("github.com/hugobyte/dive/services/cosmvm/archway/archway.star") neutron_node_service = import_module("github.com/hugobyte/dive/services/cosmvm/neutron/neutron.star") +parser = import_module("github.com/hugobyte/dive/package_io/input_parser.star") + def start_cosmvm_chains(plan,node_name,args): if node_name == "archway": @@ -9,6 +11,26 @@ def start_cosmvm_chains(plan,node_name,args): return neutron_node_service.start_node_service(plan,args) -def start_ibc_between_cosmvm_chains(plan,chain_a,chain_b): +def start_ibc_between_cosmvm_chains(plan, chain_a, chain_b, args): if chain_a == "archway" and chain_b == "archway": - return archway_node_service.start_nodes_services_archway(plan) \ No newline at end of file + return archway_node_service.start_nodes_services_archway(plan) + + elif chain_a == "neutron" and chain_b == "neutron": + return neutron_node_service.start_node_services(plan, args) + + elif chain_a == "neutron" and chain_b == "archway": + chain_a_service = parser.struct_to_dict(neutron_node_service.start_node_service(plan, args["src_config"])) + chain_b_service = parser.struct_to_dict(archway_node_service.start_node_service(plan, args["dst_config"])) + return struct( + src_config = chain_a_service, + dst_config = chain_b_service + ) + + elif chain_a == "archway" and chain_b == "neutron": + chain_a_service = parser.struct_to_dict(archway_node_service.start_node_service(plan, args["src_config"])) + chain_b_service = parser.struct_to_dict(neutron_node_service.start_node_service(plan, args["dst_config"])) + return struct( + src_config = chain_a_service, + dst_config = chain_b_service + ) + diff --git a/services/cosmvm/neutron/neutron.star b/services/cosmvm/neutron/neutron.star index 162cb6c1..8663c628 100644 --- a/services/cosmvm/neutron/neutron.star +++ b/services/cosmvm/neutron/neutron.star @@ -1,20 +1,114 @@ -# Import modules and constants +# Import required modules and constants neutron_node_service = import_module("github.com/hugobyte/dive/services/cosmvm/neutron/src/node-setup/start_node.star") constants = import_module("github.com/hugobyte/dive/package_io/constants.star") -neutron_service_config = constants.NEUTRON_SERVICE_CONFIG neutron_private_ports = constants.NEUTRON_PRIVATE_PORTS -neutron_public_ports = constants.NEUTRON_PUBLIC_PORTS +neutron_node1_config = constants.NEUTRON_NODE1_CONFIG +neutron_node2_config = constants.NEUTRON_NODE2_CONFIG + +def start_node_services(plan, args): + """ + Configure and start two Neutron node services, serving as the source and destination, + to establish an IBC relay connection between them. + + Args: + plan (plan): plan. + args (dict): Arguments containing data for configuring the services. + + Returns: + struct: Configuration information for the source and destination services. + """ + + data_src = args["src_config"]["data"] + data_dst = args["dst_config"]["data"] + src_chain_config = "" + dst_chain_config = "" + + if len(data_src) != 0: + # Configure the service based on provided data for source chain + chain_id = data_src["chainId"] + key = data_src["key"] + password = data_src["password"] + public_grpc = data_src["public_grpc"] + public_tcp = data_src["public_tcp"] + public_http = data_src["public_http"] + public_rpc = data_src["public_rpc"] + + src_chain_config = neutron_node_service.get_service_config( + chain_id, key, password, + neutron_private_ports.grpc, neutron_private_ports.http, neutron_private_ports.tcp, neutron_private_ports.rpc, + public_grpc, public_http, public_tcp, public_rpc + ) + else: + # Use predefined port values for configuration for source chain + src_chain_config = neutron_node_service.get_service_config( + neutron_node1_config.chain_id, neutron_node1_config.key, neutron_node1_config.password, + neutron_private_ports.grpc, neutron_private_ports.http, + neutron_private_ports.tcp, neutron_private_ports.rpc, + neutron_node1_config.grpc, neutron_node1_config.http, + neutron_node1_config.tcp, neutron_node1_config.rpc + ) + + if len(data_dst) != 0: + # Configure the service based on provided data for destination chain + chain_id = data_dst["chainId"] + key = data_dst["key"] + password = data_dst["password"] + public_grpc = data_dst["public_grpc"] + public_tcp = data_dst["public_tcp"] + public_http = data_dst["public_http"] + public_rpc = data_dst["public_rpc"] + + dst_chain_config = neutron_node_service.get_service_config( + chain_id, key, password, + neutron_private_ports.grpc, neutron_private_ports.http, neutron_private_ports.tcp, neutron_private_ports.rpc, + public_grpc, public_http, public_tcp, public_rpc + ) + else: + # Use predefined port values for configuration for destination chain + dst_chain_config = neutron_node_service.get_service_config( + neutron_node2_config.chain_id, neutron_node2_config.key, neutron_node2_config.password, + neutron_private_ports.grpc, neutron_private_ports.http, + neutron_private_ports.tcp, neutron_private_ports.rpc, + neutron_node2_config.grpc, neutron_node2_config.http, + neutron_node2_config.tcp, neutron_node2_config.rpc + ) + + # Start the source and destination Neutron node services + src_chain_response = neutron_node_service.start_neutron_node(plan, src_chain_config) + dst_chain_response = neutron_node_service.start_neutron_node(plan, dst_chain_config) + + # Create configuration dictionaries for both services + src_service_config = { + "service_name": src_chain_response.service_name, + "endpoint": src_chain_response.endpoint, + "endpoint_public": src_chain_response.endpoint_public, + "chain_id": src_chain_response.chain_id, + "chain_key": src_chain_response.chain_key + } + + dst_service_config = { + "service_name": dst_chain_response.service_name, + "endpoint": dst_chain_response.endpoint, + "endpoint_public": dst_chain_response.endpoint_public, + "chain_id": dst_chain_response.chain_id, + "chain_key": dst_chain_response.chain_key + } + + return struct( + src_config=src_service_config, + dst_config=dst_service_config, + ) def start_node_service(plan, args): """ Start a Neutron node service with the provided configuration. Args: - plan (Plan): The deployment plan. + plan (plan): plan. args (dict): Arguments containing data for configuring the service. Returns: - Any: The response from starting the Neutron node service. + struct: The response from starting the Neutron node service. """ data = args["data"] @@ -22,27 +116,27 @@ def start_node_service(plan, args): if len(data) != 0: # Configure the service based on provided data - private_grpc = data["private_grpc"] - private_tcp = data["private_tcp"] - private_http = data["private_http"] - private_rpc = data["private_rpc"] - + chain_id = data["chainId"] + key = data["key"] + password = data["password"] public_grpc = data["public_grpc"] public_tcp = data["public_tcp"] public_http = data["public_http"] public_rpc = data["public_rpc"] chain_config = neutron_node_service.get_service_config( - private_grpc, private_http, private_tcp, private_rpc, + chain_id, key, password, + neutron_private_ports.grpc, neutron_private_ports.http, neutron_private_ports.tcp, neutron_private_ports.rpc, public_grpc, public_http, public_tcp, public_rpc ) else: # Use predefined port values for configuration chain_config = neutron_node_service.get_service_config( + neutron_node1_config.chain_id, neutron_node1_config.key, neutron_node1_config.password, neutron_private_ports.grpc, neutron_private_ports.http, neutron_private_ports.tcp, neutron_private_ports.rpc, - neutron_public_ports.grpc, neutron_public_ports.http, - neutron_public_ports.tcp, neutron_public_ports.rpc + neutron_node1_config.grpc, neutron_node1_config.http, + neutron_node1_config.tcp, neutron_node1_config.rpc ) # Start the Neutron node service and return the response diff --git a/services/cosmvm/neutron/src/node-setup/start_node.star b/services/cosmvm/neutron/src/node-setup/start_node.star index f7d5889c..adb65f62 100644 --- a/services/cosmvm/neutron/src/node-setup/start_node.star +++ b/services/cosmvm/neutron/src/node-setup/start_node.star @@ -8,20 +8,36 @@ def start_neutron_node(plan, args): Start a Neutron node service with the provided configuration. Args: - plan (Plan): The deployment plan. + plan (plan): plan. args (dict): Arguments for configuring the service. Returns: - None + struct: Service configuration """ + chain_id = args["cid"] + key = args["key"] + password = args["password"] service_name = args["service_name"] plan.print("Launching " + service_name + " deployment service") + start_script_file = "start-script-%s" % chain_id + init_script_file = "init-script-%s" % chain_id + init_neutrond_script_file = "init-neutrond-script-%s" % chain_id + + plan.upload_files(src = neutron_node_constants.init_script, name = init_script_file) + plan.upload_files(src = neutron_node_constants.init_nutrond_script, name = init_neutrond_script_file) + plan.upload_files(src = neutron_node_constants.start_script, name = start_script_file) + # Define Neutron node configuration neutron_node_config = ServiceConfig( image=neutron_node_constants.image, + files = { + neutron_node_constants.path + "start": start_script_file, + neutron_node_constants.path + "init": init_script_file, + neutron_node_constants.path + "init-neutrond": init_neutrond_script_file, + }, ports={ network_port_keys_and_ip.http: PortSpec( number=args["private_http"], @@ -75,7 +91,8 @@ def start_neutron_node(plan, args): wait = "2m" ), }, - entrypoint=["/bin/sh", "-c", "bash /opt/neutron/network/init.sh && bash /opt/neutron/network/init-neutrond.sh && bash /opt/neutron/network/start.sh"], + entrypoint=["/bin/sh", "-c"], + cmd = ["chmod +x ../..%s/init/init.sh && chmod +x ../..%s/start/start.sh && chmod +x ../..%s/init-neutrond/init-neutrond.sh && key=%s password=\"%s\" CHAINID=%s ../..%s/init/init.sh && CHAINID=%s ../..%s/init-neutrond/init-neutrond.sh && CHAINID=%s ../..%s/start/start.sh" % (neutron_node_constants.path, neutron_node_constants.path, neutron_node_constants.path, key, password, chain_id, neutron_node_constants.path, chain_id,neutron_node_constants.path, chain_id, neutron_node_constants.path)], env_vars={ "RUN_BACKGROUND": "0", }, @@ -94,6 +111,8 @@ def start_neutron_node(plan, args): service_name = service_name, endpoint = private_url, endpoint_public = public_url, + chain_id = chain_id, + chain_key = key ) @@ -115,11 +134,14 @@ def get_service_url(ip_address, ports): return url -def get_service_config(private_grpc, private_http, private_tcp, private_rpc, public_grpc, public_http, public_tcp, public_rpc): +def get_service_config(cid, key, password, private_grpc, private_http, private_tcp, private_rpc, public_grpc, public_http, public_tcp, public_rpc): """ Get the service configuration based on provided port values. Args: + cid (str): Chain id. + key (str): Key. + password (str): Memonic password combine with words between 20 - 34 private_grpc (int): Private gRPC port. private_http (int): Private HTTP port. private_tcp (int): Private TCP port. @@ -135,7 +157,7 @@ def get_service_config(private_grpc, private_http, private_tcp, private_rpc, pub dict: Service configuration dictionary. """ - service_name = "{0}".format(neutron_node_constants.service_name) + service_name = "{0}-{1}".format(neutron_node_constants.service_name, cid) config = { "public_grpc": public_grpc, "public_http": public_http, @@ -146,5 +168,8 @@ def get_service_config(private_grpc, private_http, private_tcp, private_rpc, pub "private_rpc": private_rpc, "private_grpc": private_grpc, "service_name": service_name, + "cid" : cid, + "key" : key, + "password" : password, } return config diff --git a/services/cosmvm/neutron/static_files/init-neutrond.sh b/services/cosmvm/neutron/static_files/init-neutrond.sh new file mode 100644 index 00000000..966db3f0 --- /dev/null +++ b/services/cosmvm/neutron/static_files/init-neutrond.sh @@ -0,0 +1,627 @@ +#!/bin/bash +set -e + + +key=${key:-test-key} +password=${password:-clock post desk civil pottery foster expand merit dash seminar song memory figure uniform spice circle try happy obvious trash crime hybrid hood cushion} + +BINARY=${BINARY:-neutrond} +BASE_DIR=./data +CHAINID=${CHAINID:-test-1} +STAKEDENOM=${STAKEDENOM:-untrn} +CONTRACTS_BINARIES_DIR=${CONTRACTS_BINARIES_DIR:-./contracts} +THIRD_PARTY_CONTRACTS_DIR=${THIRD_PARTY_CONTRACTS_DIR:-./contracts_thirdparty} + +CHAIN_DIR="$BASE_DIR/$CHAINID" +GENESIS_PATH="$CHAIN_DIR/config/genesis.json" + +ADMIN_ADDRESS=$($BINARY keys show demowallet1 -a --home "$CHAIN_DIR" --keyring-backend test) +# MAIN_DAO +DAO_CONTRACT=$CONTRACTS_BINARIES_DIR/cwd_core.wasm +PRE_PROPOSAL_CONTRACT=$CONTRACTS_BINARIES_DIR/cwd_pre_propose_single.wasm +PRE_PROPOSAL_MULTIPLE_CONTRACT=$CONTRACTS_BINARIES_DIR/cwd_pre_propose_multiple.wasm +PRE_PROPOSAL_OVERRULE_CONTRACT=$CONTRACTS_BINARIES_DIR/cwd_pre_propose_overrule.wasm +PROPOSAL_CONTRACT=$CONTRACTS_BINARIES_DIR/cwd_proposal_single.wasm +PROPOSAL_MULTIPLE_CONTRACT=$CONTRACTS_BINARIES_DIR/cwd_proposal_multiple.wasm +VOTING_REGISTRY_CONTRACT=$CONTRACTS_BINARIES_DIR/neutron_voting_registry.wasm +# VAULTS +NEUTRON_VAULT_CONTRACT=$CONTRACTS_BINARIES_DIR/neutron_vault.wasm +# RESERVE +RESERVE_CONTRACT=$CONTRACTS_BINARIES_DIR/neutron_reserve.wasm +DISTRIBUTION_CONTRACT=$CONTRACTS_BINARIES_DIR/neutron_distribution.wasm +# SUBDAOS +SUBDAO_CORE_CONTRACT=$CONTRACTS_BINARIES_DIR/cwd_subdao_core.wasm +SUBDAO_TIMELOCK_CONTRACT=$CONTRACTS_BINARIES_DIR/cwd_subdao_timelock_single.wasm +SUBDAO_PRE_PROPOSE_CONTRACT=$CONTRACTS_BINARIES_DIR/cwd_subdao_pre_propose_single.wasm +SUBDAO_PROPOSAL_CONTRACT=$CONTRACTS_BINARIES_DIR/cwd_subdao_proposal_single.wasm +CW4_VOTING_CONTRACT=$THIRD_PARTY_CONTRACTS_DIR/cw4_voting.wasm +CW4_GROUP_CONTRACT=$THIRD_PARTY_CONTRACTS_DIR/cw4_group.wasm + +echo "Add consumer section..." +$BINARY add-consumer-section --home "$CHAIN_DIR" +### PARAMETERS SECTION + +## slashing params +SLASHING_SIGNED_BLOCKS_WINDOW=140000 +SLASHING_MIN_SIGNED=0.050000000000000000 +SLASHING_FRACTION_DOUBLE_SIGN=0.010000000000000000 +SLASHING_FRACTION_DOWNTIME=0.000100000000000000 + +##pre propose single parameters +PRE_PROPOSAL_SINGLE_AMOUNT=1000 +PRE_PROPOSAL_SINGLE_REFUND_POLICY="only_passed" +PRE_PROPOSAL_SINGLE_OPEN_PROPOSAL_SUBMISSION=false + +## proposal singe params +PROPOSAL_ALLOW_REVOTING=false # should be true for non-testing env +PROPOSAL_SINGLE_ONLY_MEMBERS_EXECUTE=false +PROPOSAL_SINGLE_ONLY_MAX_VOTING_PERIOD=1200 # seconds; should be 2 weeks in production +PROPOSAL_SINGLE_CLOSE_PROPOSAL_ON_EXECUTION_FAILURE=false +PROPOSAL_SINGLE_QUORUM=0.05 # quorum to consider proposal's result viable [float] < 1 +PROPOSAL_SINGLE_THRESHOLD=0.5 # % of votes should vote for the proposal to pass [float] <1 +PROPOSAL_SINGLE_LABEL="neutron.proposals.single" +PRE_PROPOSAL_SINGLE_LABEL="neutron.proposals.single.pre_propose" + +## propose multiple params +PROPOSAL_MULTIPLE_ALLOW_REVOTING=false # should be true for non-testing env +PROPOSAL_MULTIPLE_ONLY_MEMBERS_EXECUTE=false +PROPOSAL_MULTIPLE_ONLY_MAX_VOTING_PERIOD=1200 # seconds; should be 2 weeks in production +PROPOSAL_MULTIPLE_CLOSE_PROPOSAL_ON_EXECUTION_FAILURE=false +PROPOSAL_MULTIPLE_QUORUM=0.05 # quorum to consider proposal's result viable [float] < 1 +PROPOSAL_MULTIPLE_LABEL="neutron.proposals.multiple" +PRE_PROPOSAL_MULTIPLE_LABEL="neutron.proposals.multiple.pre_propose" + +## Propose overrule params +PROPOSAL_OVERRULE_ALLOW_REVOTING=false +PROPOSAL_OVERRULE_ONLY_MEMBERS_EXECUTE=false +PROPOSAL_OVERRULE_ONLY_MAX_VOTING_PERIOD=1200 # seconds; should be 3 days in production +PROPOSAL_OVERRULE_CLOSE_PROPOSAL_ON_EXECUTION_FAILURE=false +PROPOSAL_OVERRULE_THRESHOLD=0.005 # around 10 times lower than for regular proposals +PROPOSAL_OVERRULE_LABEL="neutron.proposals.overrule" +PRE_PROPOSE_OVERRULE_LABEL="neutron.proposals.overrule.pre_propose" + +## Voting registry +VOTING_REGISTRY_LABEL="neutron.voting" + +## DAO +DAO_NAME="Neutron DAO" +DAO_DESCRIPTION="Neutron DAO is a DAO DAO-based governance of Neutron chain" +DAO_CORE_LABEL="neutron.core" + +## Neutron vault +NEUTRON_VAULT_NAME="Neutron Vault" +NEUTRON_VAULT_DESCRIPTION="Vault to put NTRN tokens to get voting power" +NEUTRON_VAULT_LABEL="neutron.voting.vaults.neutron" + +## Reserve +RESERVE_DISTRIBUTION_RATE=0 +RESERVE_MIN_PERIOD=10 +RESERVE_VESTING_DENOMINATOR=1 +RESERVE_LABEL="reserve" + +DISTRIBUTION_LABEL="distribution" + +## Grants subdao +GRANTS_SUBDAO_CORE_NAME="Grants SubDAO" +GRANTS_SUBDAO_CORE_DESCRIPTION="SubDAO to distribute grants to projects" +GRANTS_SUBDAO_CORE_LABEL="neutron.subdaos.grants.core" +GRANTS_SUBDAO_PROPOSAL_LABEL="neutron.subdaos.grants.proposals.single" +GRANTS_SUBDAO_PRE_PROPOSE_LABEL="neutron.subdaos.grants.proposals.single.pre_propose" +GRANTS_SUBDAO_VOTING_MODULE_LABEL="neutron.subdaos.grants.voting" + +## Timelock +GRANTS_SUBDAO_TIMELOCK_LABEL="neutron.subdaos.grants.proposals.single.pre_propose.timelock" + +## Security subdao +SECURITY_SUBDAO_CORE_NAME="Security SubDAO" +SECURITY_SUBDAO_CORE_DESCRIPTION="SubDAO with power to pause specific Neutron DAO modules" +SECURITY_SUBDAO_CORE_LABEL="neutron.subdaos.security.core" +SECURITY_SUBDAO_PROPOSAL_LABEL="neutron.subdaos.security.proposals.single" +SECURITY_SUBDAO_PRE_PROPOSE_LABEL="neutron.subdaos.security.proposals.single.pre_propose" +SECURITY_SUBDAO_VOTE_LABEL="neutron.subdaos.security.voting" + +echo "Initializing dao contract in genesis..." + +function store_binary() { + CONTRACT_BINARY_PATH=$1 + $BINARY add-wasm-message store "$CONTRACT_BINARY_PATH" \ + --output json --run-as "${ADMIN_ADDRESS}" --keyring-backend=test --home "$CHAIN_DIR" + BINARY_ID=$(jq -r "[.app_state.wasm.gen_msgs[] | select(.store_code != null)] | length" "$CHAIN_DIR/config/genesis.json") + echo "$BINARY_ID" +} + +# Upload the dao contracts +# MAIN_DAO +DAO_CONTRACT_BINARY_ID=$(store_binary "$DAO_CONTRACT") +PRE_PROPOSAL_CONTRACT_BINARY_ID=$(store_binary "$PRE_PROPOSAL_CONTRACT") +PRE_PROPOSAL_MULTIPLE_CONTRACT_BINARY_ID=$(store_binary "$PRE_PROPOSAL_MULTIPLE_CONTRACT") +PRE_PROPOSAL_OVERRULE_CONTRACT_BINARY_ID=$(store_binary "$PRE_PROPOSAL_OVERRULE_CONTRACT") +PROPOSAL_CONTRACT_BINARY_ID=$(store_binary "$PROPOSAL_CONTRACT") +PROPOSAL_MULTIPLE_CONTRACT_BINARY_ID=$(store_binary "$PROPOSAL_MULTIPLE_CONTRACT") +VOTING_REGISTRY_CONTRACT_BINARY_ID=$(store_binary "$VOTING_REGISTRY_CONTRACT") +# VAULTS +NEUTRON_VAULT_CONTRACT_BINARY_ID=$(store_binary "$NEUTRON_VAULT_CONTRACT") +# RESERVE +DISTRIBUTION_CONTRACT_BINARY_ID=$(store_binary "$DISTRIBUTION_CONTRACT") +RESERVE_CONTRACT_BINARY_ID=$(store_binary "$RESERVE_CONTRACT") +# SUBDAOS +SUBDAO_CORE_BINARY_ID=$(store_binary "$SUBDAO_CORE_CONTRACT") +SUBDAO_TIMELOCK_BINARY_ID=$(store_binary "$SUBDAO_TIMELOCK_CONTRACT") +SUBDAO_PRE_PROPOSE_BINARY_ID=$(store_binary "$SUBDAO_PRE_PROPOSE_CONTRACT") +SUBDAO_PROPOSAL_BINARY_ID=$(store_binary "$SUBDAO_PROPOSAL_CONTRACT") +CW4_VOTING_CONTRACT_BINARY_ID=$(store_binary "$CW4_VOTING_CONTRACT") +CW4_GROUP_CONTRACT_BINARY_ID=$(store_binary "$CW4_GROUP_CONTRACT") + +# WARNING! +# The following code is needed to pre-generate the contract addresses +# Those addresses depend on the ORDER OF CONTRACTS INITIALIZATION +# Thus, this code section depends a lot on the order and content of the instantiate-contract commands at the end script +# It also depends on the implicitly initialized contracts (e.g. DAO core instantiation also instantiate proposals and stuff) +# If you're to do any changes, please do it consistently in both sections +# If you're to do add any implicitly initialized contracts in init messages, please reflect changes here + +function genaddr() { + CODE_ID=$1 + CONTRACT_ADDRESS=$($BINARY debug generate-contract-address "$INSTANCE_ID_COUNTER" "$CODE_ID") + echo "$CONTRACT_ADDRESS" +} + +INSTANCE_ID_COUNTER=1 + +# VAULTS +NEUTRON_VAULT_CONTRACT_ADDRESS=$(genaddr "$NEUTRON_VAULT_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) + +# MAIN_DAO +DAO_CONTRACT_ADDRESS=$(genaddr "$DAO_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +PROPOSAL_SINGLE_CONTRACT_ADDRESS=$(genaddr "$PROPOSAL_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +PRE_PROPOSAL_CONTRACT_ADDRESS=$(genaddr "$PRE_PROPOSAL_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +PROPOSAL_MULTIPLE_CONTRACT_ADDRESS=$(genaddr "$PROPOSAL_MULTIPLE_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +PRE_PROPOSAL_MULTIPLE_CONTRACT_ADDRESS=$(genaddr "$PRE_PROPOSAL_MULTIPLE_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +PROPOSAL_OVERRULE_CONTRACT_ADDRESS=$(genaddr "$PROPOSAL_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +PRE_PROPOSAL_OVERRULE_CONTRACT_ADDRESS=$(genaddr "$PRE_PROPOSAL_OVERRULE_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +VOTING_REGISTRY_CONTRACT_ADDRESS=$(genaddr "$VOTING_REGISTRY_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) + +# RESERVE +RESERVE_CONTRACT_ADDRESS=$(genaddr "$RESERVE_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +DISTRIBUTION_CONTRACT_ADDRESS=$(genaddr "$DISTRIBUTION_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +# SUBDAOS +SECURITY_SUBDAO_CORE_CONTRACT_ADDRESS=$(genaddr "$SUBDAO_CORE_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +SECURITY_SUBDAO_PROPOSAL_CONTRACT_ADDRESS=$(genaddr "$SUBDAO_PROPOSAL_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +SECURITY_SUBDAO_PRE_PROPOSE_CONTRACT_ADDRESS=$(genaddr "$SUBDAO_PROPOSAL_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +SECURITY_SUBDAO_VOTING_CONTRACT_ADDRESS=$(genaddr "$CW4_VOTING_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +SECURITY_SUBDAO_GROUP_CONTRACT_ADDRESS=$(genaddr "$CW4_GROUP_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +GRANTS_SUBDAO_CORE_CONTRACT_ADDRESS=$(genaddr "$SUBDAO_CORE_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +GRANTS_SUBDAO_PROPOSAL_CONTRACT_ADDRESS=$(genaddr "$SUBDAO_PROPOSAL_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +GRANTS_SUBDAO_PRE_PROPOSE_CONTRACT_ADDRESS=$(genaddr "$SUBDAO_PRE_PROPOSE_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +GRANTS_SUBDAO_TIMELOCK_CONTRACT_ADDRESS=$(genaddr "$SUBDAO_TIMELOCK_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +GRANTS_SUBDAO_VOTING_CONTRACT_ADDRESS=$(genaddr "$CW4_VOTING_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) +GRANTS_SUBDAO_GROUP_CONTRACT_ADDRESS=$(genaddr "$CW4_GROUP_CONTRACT_BINARY_ID") && (( INSTANCE_ID_COUNTER++ )) + +function check_json() { + MSG=$1 + if ! jq -e . >/dev/null 2>&1 <<<"$MSG"; then + echo "Failed to parse JSON for $MSG" >&2 + exit 1 + fi +} + +function json_to_base64() { + MSG=$1 + check_json "$MSG" + echo "$MSG" | base64 | tr -d "\n" +} + +# PRE_PROPOSE_INIT_MSG will be put into the PROPOSAL_SINGLE_INIT_MSG and PROPOSAL_MULTIPLE_INIT_MSG +PRE_PROPOSE_INIT_MSG='{ + "deposit_info":{ + "denom":{ + "token":{ + "denom":{ + "native":"'"$STAKEDENOM"'" + } + } + }, + "amount": "'"$PRE_PROPOSAL_SINGLE_AMOUNT"'", + "refund_policy":"'"$PRE_PROPOSAL_SINGLE_REFUND_POLICY"'" + }, + "open_proposal_submission": '"$PRE_PROPOSAL_SINGLE_OPEN_PROPOSAL_SUBMISSION"' +}' +PRE_PROPOSE_INIT_MSG_BASE64=$(json_to_base64 "$PRE_PROPOSE_INIT_MSG") + +# -------------------- PROPOSE-SINGLE { PRE-PROPOSE } -------------------- + +PROPOSAL_SINGLE_INIT_MSG='{ + "allow_revoting":'"$PROPOSAL_ALLOW_REVOTING"', + "pre_propose_info":{ + "module_may_propose":{ + "info":{ + "admin": { + "core_module": {} + }, + "code_id": '"$PRE_PROPOSAL_CONTRACT_BINARY_ID"', + "msg": "'"$PRE_PROPOSE_INIT_MSG_BASE64"'", + "label": "'"$PRE_PROPOSAL_SINGLE_LABEL"'" + } + } + }, + "only_members_execute":'"$PROPOSAL_SINGLE_ONLY_MEMBERS_EXECUTE"', + "max_voting_period":{ + "time":'"$PROPOSAL_SINGLE_ONLY_MAX_VOTING_PERIOD"' + }, + "close_proposal_on_execution_failure":'"$PROPOSAL_SINGLE_CLOSE_PROPOSAL_ON_EXECUTION_FAILURE"', + "threshold":{ + "threshold_quorum":{ + "quorum":{ + "percent":"'"$PROPOSAL_SINGLE_QUORUM"'" + }, + "threshold":{ + "percent":"'"$PROPOSAL_SINGLE_THRESHOLD"'" + } + } + } +}' +PROPOSAL_SINGLE_INIT_MSG_BASE64=$(json_to_base64 "$PROPOSAL_SINGLE_INIT_MSG") + +# -------------------- PROPOSE-MULTIPLE { PRE-PROPOSE } -------------------- + +PROPOSAL_MULTIPLE_INIT_MSG='{ + "allow_revoting":'"$PROPOSAL_MULTIPLE_ALLOW_REVOTING"', + "pre_propose_info":{ + "module_may_propose":{ + "info":{ + "admin": { + "core_module": {} + }, + "code_id": '"$PRE_PROPOSAL_MULTIPLE_CONTRACT_BINARY_ID"', + "msg": "'"$PRE_PROPOSE_INIT_MSG_BASE64"'", + "label": "'"$PRE_PROPOSAL_MULTIPLE_LABEL"'" + } + } + }, + "only_members_execute":'"$PROPOSAL_MULTIPLE_ONLY_MEMBERS_EXECUTE"', + "max_voting_period":{ + "time":'"$PROPOSAL_MULTIPLE_ONLY_MAX_VOTING_PERIOD"' + }, + "close_proposal_on_execution_failure": '"$PROPOSAL_MULTIPLE_CLOSE_PROPOSAL_ON_EXECUTION_FAILURE"', + "voting_strategy":{ + "single_choice": { + "quorum": { + "percent": "'"$PROPOSAL_MULTIPLE_QUORUM"'" + } + } + } +}' +PROPOSAL_MULTIPLE_INIT_MSG_BASE64=$(json_to_base64 "$PROPOSAL_MULTIPLE_INIT_MSG") + +# PRE_PROPOSE_OVERRULE_INIT_MSG will be put into the PROPOSAL_OVERRULE_INIT_MSG +PRE_PROPOSE_OVERRULE_INIT_MSG='{}' +PRE_PROPOSE_OVERRULE_INIT_MSG_BASE64=$(json_to_base64 "$PRE_PROPOSE_OVERRULE_INIT_MSG") + + +# -------------------- PROPOSE-OVERRULE { PRE-PROPOSE-OVERRULE } -------------------- + +PROPOSAL_OVERRULE_INIT_MSG='{ + "allow_revoting":'"$PROPOSAL_OVERRULE_ALLOW_REVOTING"', + "pre_propose_info":{ + "module_may_propose":{ + "info":{ + "admin": { + "core_module": {} + }, + "code_id": '"$PRE_PROPOSAL_OVERRULE_CONTRACT_BINARY_ID"', + "msg": "'"$PRE_PROPOSE_OVERRULE_INIT_MSG_BASE64"'", + "label": "'"$PRE_PROPOSE_OVERRULE_LABEL"'" + } + } + }, + "only_members_execute": '"$PROPOSAL_OVERRULE_ONLY_MEMBERS_EXECUTE"', + "max_voting_period":{ + "time": '"$PROPOSAL_OVERRULE_ONLY_MAX_VOTING_PERIOD"' + }, + "close_proposal_on_execution_failure": '"$PROPOSAL_OVERRULE_CLOSE_PROPOSAL_ON_EXECUTION_FAILURE"', + "threshold":{ + "absolute_percentage":{ + "percentage":{ + "percent": "'"$PROPOSAL_OVERRULE_THRESHOLD"'" + } + } + } +}' +PROPOSAL_OVERRULE_INIT_MSG_BASE64=$(json_to_base64 "$PROPOSAL_OVERRULE_INIT_MSG") + +VOTING_REGISTRY_INIT_MSG='{ + "owner": "'"$DAO_CONTRACT_ADDRESS"'", + "voting_vaults": [ + "'"$NEUTRON_VAULT_CONTRACT_ADDRESS"'" + ] +}' +VOTING_REGISTRY_INIT_MSG_BASE64=$(json_to_base64 "$VOTING_REGISTRY_INIT_MSG") + +DAO_INIT='{ + "description": "'"$DAO_DESCRIPTION"'", + "name": "'"$DAO_NAME"'", + "proposal_modules_instantiate_info": [ + { + "admin": { + "core_module": {} + }, + "code_id": '"$PROPOSAL_CONTRACT_BINARY_ID"', + "label": "'"$PROPOSAL_SINGLE_LABEL"'", + "msg": "'"$PROPOSAL_SINGLE_INIT_MSG_BASE64"'" + }, + { + "admin": { + "core_module": {} + }, + "code_id": '"$PROPOSAL_MULTIPLE_CONTRACT_BINARY_ID"', + "label": "'"$PROPOSAL_MULTIPLE_LABEL"'", + "msg": "'"$PROPOSAL_MULTIPLE_INIT_MSG_BASE64"'" + }, + { + "admin": { + "core_module": {} + }, + "code_id": '"$PROPOSAL_CONTRACT_BINARY_ID"', + "label": "'"$PROPOSAL_OVERRULE_LABEL"'", + "msg": "'"$PROPOSAL_OVERRULE_INIT_MSG_BASE64"'" + } + ], + "voting_registry_module_instantiate_info": { + "admin": { + "core_module": {} + }, + "code_id": '"$VOTING_REGISTRY_CONTRACT_BINARY_ID"', + "label": "'"$VOTING_REGISTRY_LABEL"'", + "msg": "'"$VOTING_REGISTRY_INIT_MSG_BASE64"'" + } +}' + +# RESERVE +RESERVE_INIT='{ + "main_dao_address": "'"$DAO_CONTRACT_ADDRESS"'", + "security_dao_address": "'"$SECURITY_SUBDAO_CORE_CONTRACT_ADDRESS"'", + "denom": "'"$STAKEDENOM"'", + "distribution_rate": "'"$RESERVE_DISTRIBUTION_RATE"'", + "min_period": '"$RESERVE_MIN_PERIOD"', + "distribution_contract": "'"$DISTRIBUTION_CONTRACT_ADDRESS"'", + "treasury_contract": "'"$DAO_CONTRACT_ADDRESS"'", + "vesting_denominator": "'"$RESERVE_VESTING_DENOMINATOR"'" +}' + +DISTRIBUTION_INIT='{ + "main_dao_address": "'"$DAO_CONTRACT_ADDRESS"'", + "security_dao_address": "'"$SECURITY_SUBDAO_CORE_CONTRACT_ADDRESS"'", + "denom": "'"$STAKEDENOM"'" +}' + +# VAULTS + +NEUTRON_VAULT_INIT='{ + "owner": "'"$DAO_CONTRACT_ADDRESS"'", + "name": "'"$NEUTRON_VAULT_NAME"'", + "denom": "'"$STAKEDENOM"'", + "description": "'"$NEUTRON_VAULT_DESCRIPTION"'" +}' + +# CW4 MODULES FOR SUBDAOS + +CW4_VOTE_INIT_MSG='{ + "cw4_group_code_id": '"$CW4_GROUP_CONTRACT_BINARY_ID"', + "initial_members": [ + { + "addr": "'"$ADMIN_ADDRESS"'", + "weight": 1 + } + ] +}' +CW4_VOTE_INIT_MSG_BASE64=$(json_to_base64 "$CW4_VOTE_INIT_MSG") + +# SECURITY_SUBDAO + +# SECURITY_SUBDAO_PRE_PROPOSE_INIT_MSG will be put into the SECURITY_SUBDAO_PROPOSAL_INIT_MSG +SECURITY_SUBDAO_PRE_PROPOSE_INIT_MSG='{ + "open_proposal_submission": false +}' +SECURITY_SUBDAO_PRE_PROPOSE_INIT_MSG_BASE64=$(json_to_base64 "$SECURITY_SUBDAO_PRE_PROPOSE_INIT_MSG") + +SECURITY_SUBDAO_PROPOSAL_INIT_MSG='{ + "allow_revoting": false, + "pre_propose_info":{ + "module_may_propose":{ + "info":{ + "admin": { + "address": { + "addr": "'"$DAO_CONTRACT_ADDRESS"'" + } + }, + "code_id": '"$PRE_PROPOSAL_CONTRACT_BINARY_ID"', + "msg": "'"$SECURITY_SUBDAO_PRE_PROPOSE_INIT_MSG_BASE64"'", + "label": "'"$SECURITY_SUBDAO_PRE_PROPOSE_LABEL"'" + } + } + }, + "only_members_execute":false, + "max_voting_period":{ + "height": 1000000000000 + }, + "close_proposal_on_execution_failure":false, + "threshold":{ + "absolute_count":{ + "threshold": "1" + } + } +}' +SECURITY_SUBDAO_PROPOSAL_INIT_MSG_BASE64=$(json_to_base64 "$SECURITY_SUBDAO_PROPOSAL_INIT_MSG") + +SECURITY_SUBDAO_CORE_INIT_MSG='{ + "name": "'"$SECURITY_SUBDAO_CORE_NAME"'", + "description": "'"$SECURITY_SUBDAO_CORE_DESCRIPTION"'", + "vote_module_instantiate_info": { + "admin": { + "address": { + "addr": "'"$DAO_CONTRACT_ADDRESS"'" + } + }, + "code_id": '"$CW4_VOTING_CONTRACT_BINARY_ID"', + "label": "'"$SECURITY_SUBDAO_VOTE_LABEL"'", + "msg": "'"$CW4_VOTE_INIT_MSG_BASE64"'" + }, + "proposal_modules_instantiate_info": [ + { + "admin": { + "address": { + "addr": "'"$DAO_CONTRACT_ADDRESS"'" + } + }, + "code_id": '"$SUBDAO_PROPOSAL_BINARY_ID"', + "label": "'"$SECURITY_SUBDAO_PROPOSAL_LABEL"'", + "msg": "'"$SECURITY_SUBDAO_PROPOSAL_INIT_MSG_BASE64"'" + } + ], + "main_dao": "'"$DAO_CONTRACT_ADDRESS"'", + "security_dao": "'"$SECURITY_SUBDAO_CORE_CONTRACT_ADDRESS"'" +}' + +# GRANTS_SUBDAO + +GRANTS_SUBDAO_TIMELOCK_INIT_MSG='{ + "overrule_pre_propose": "'"$PROPOSAL_OVERRULE_CONTRACT_ADDRESS"'" +}' +GRANTS_SUBDAO_TIMELOCK_INIT_MSG_BASE64=$(json_to_base64 "$GRANTS_SUBDAO_TIMELOCK_INIT_MSG") + +GRANTS_SUBDAO_PRE_PROPOSE_INIT_MSG='{ + "open_proposal_submission": true, + "timelock_module_instantiate_info": { + "admin": { + "address": { + "addr": "'"$DAO_CONTRACT_ADDRESS"'" + } + }, + "code_id": '"$SUBDAO_TIMELOCK_BINARY_ID"', + "label": "'"$GRANTS_SUBDAO_TIMELOCK_LABEL"'", + "msg": "'"$GRANTS_SUBDAO_TIMELOCK_INIT_MSG_BASE64"'" + } +}' +GRANTS_SUBDAO_PRE_PROPOSE_INIT_MSG_BASE64=$(json_to_base64 "$GRANTS_SUBDAO_PRE_PROPOSE_INIT_MSG") + +GRANTS_SUBDAO_PROPOSAL_INIT_MSG='{ + "allow_revoting": false, + "pre_propose_info":{ + "module_may_propose":{ + "info":{ + "admin": { + "address": { + "addr": "'"$DAO_CONTRACT_ADDRESS"'" + } + }, + "code_id": '"$SUBDAO_PRE_PROPOSE_BINARY_ID"', + "msg": "'"$GRANTS_SUBDAO_PRE_PROPOSE_INIT_MSG_BASE64"'", + "label": "'"$GRANTS_SUBDAO_PRE_PROPOSE_LABEL"'" + } + } + }, + "only_members_execute":false, + "max_voting_period":{ + "height": 1000000000000 + }, + "close_proposal_on_execution_failure":false, + "threshold":{ + "absolute_count":{ + "threshold": "1" + } + } +}' +GRANTS_SUBDAO_PROPOSAL_INIT_MSG_BASE64=$(json_to_base64 "$GRANTS_SUBDAO_PROPOSAL_INIT_MSG") + +GRANTS_SUBDAO_CORE_INIT_MSG='{ + "name": "'"$GRANTS_SUBDAO_CORE_NAME"'", + "description": "'"$GRANTS_SUBDAO_CORE_DESCRIPTION"'", + "vote_module_instantiate_info": { + "admin": { + "address": { + "addr": "'"$DAO_CONTRACT_ADDRESS"'" + } + }, + "code_id": '"$CW4_VOTING_CONTRACT_BINARY_ID"', + "label": "'"$GRANTS_SUBDAO_VOTING_MODULE_LABEL"'", + "msg": "'"$CW4_VOTE_INIT_MSG_BASE64"'" + }, + "proposal_modules_instantiate_info": [ + { + "admin": { + "address": { + "addr": "'"$DAO_CONTRACT_ADDRESS"'" + } + }, + "code_id": '"$SUBDAO_PROPOSAL_BINARY_ID"', + "label": "'"$GRANTS_SUBDAO_PROPOSAL_LABEL"'", + "msg": "'"$GRANTS_SUBDAO_PROPOSAL_INIT_MSG_BASE64"'" + } + ], + "main_dao": "'"$DAO_CONTRACT_ADDRESS"'", + "security_dao": "'"$SECURITY_SUBDAO_CORE_CONTRACT_ADDRESS"'" +}' + +echo "Instantiate contracts" + +function init_contract() { + BINARY_ID=$1 + INIT_MSG=$2 + LABEL=$3 + check_json "$INIT_MSG" + $BINARY add-wasm-message instantiate-contract "$BINARY_ID" "$INIT_MSG" --label "$LABEL" \ + --run-as "$DAO_CONTRACT_ADDRESS" --admin "$DAO_CONTRACT_ADDRESS" --home "$CHAIN_DIR" +} + +# WARNING! +# The following code is to add contracts instantiations messages to genesis +# It affects the section of predicting contracts addresses at the beginning of the script +# If you're to do any changes, please do it consistently in both sections +init_contract "$NEUTRON_VAULT_CONTRACT_BINARY_ID" "$NEUTRON_VAULT_INIT" "$NEUTRON_VAULT_LABEL" +init_contract "$DAO_CONTRACT_BINARY_ID" "$DAO_INIT" "$DAO_CORE_LABEL" +init_contract "$RESERVE_CONTRACT_BINARY_ID" "$RESERVE_INIT" "$RESERVE_LABEL" +init_contract "$DISTRIBUTION_CONTRACT_BINARY_ID" "$DISTRIBUTION_INIT" "$DISTRIBUTION_LABEL" +init_contract "$SUBDAO_CORE_BINARY_ID" "$SECURITY_SUBDAO_CORE_INIT_MSG" "$SECURITY_SUBDAO_CORE_LABEL" +init_contract "$SUBDAO_CORE_BINARY_ID" "$GRANTS_SUBDAO_CORE_INIT_MSG" "$GRANTS_SUBDAO_CORE_LABEL" + +ADD_SUBDAOS_MSG='{ + "update_sub_daos": { + "to_add": [ + { + "addr": "'"$SECURITY_SUBDAO_CORE_CONTRACT_ADDRESS"'" + }, + { + "addr": "'"$GRANTS_SUBDAO_CORE_CONTRACT_ADDRESS"'" + } + ], + "to_remove": [] + } +}' +check_json "$ADD_SUBDAOS_MSG" + +$BINARY add-wasm-message execute "$DAO_CONTRACT_ADDRESS" "$ADD_SUBDAOS_MSG" \ + --run-as "$DAO_CONTRACT_ADDRESS" --home "$CHAIN_DIR" + +function set_genesis_param() { + param_name=$1 + param_value=$2 + sed -i -e "s/\"$param_name\":.*/\"$param_name\": $param_value/g" "$GENESIS_PATH" +} + +set_genesis_param admins "[\"$DAO_CONTRACT_ADDRESS\"]" # admin module +set_genesis_param treasury_address "\"$DAO_CONTRACT_ADDRESS\"" # feeburner +set_genesis_param fee_collector_address "\"$DAO_CONTRACT_ADDRESS\"" # tokenfactory +set_genesis_param security_address "\"$SECURITY_SUBDAO_CORE_CONTRACT_ADDRESS\"," # cron +set_genesis_param limit 5 # cron +set_genesis_param allow_messages "[\"*\"]" # interchainaccounts +set_genesis_param signed_blocks_window "\"$SLASHING_SIGNED_BLOCKS_WINDOW\"," # slashing +set_genesis_param min_signed_per_window "\"$SLASHING_MIN_SIGNED\"," # slashing +set_genesis_param slash_fraction_double_sign "\"$SLASHING_FRACTION_DOUBLE_SIGN\"," # slashing +set_genesis_param slash_fraction_downtime "\"$SLASHING_FRACTION_DOWNTIME\"" # slashing + +if ! jq -e . "$GENESIS_PATH" >/dev/null 2>&1; then + echo "genesis appears to become incorrect json" >&2 + exit 1 +fi + +echo "DAO $DAO_CONTRACT_ADDRESS" \ No newline at end of file diff --git a/services/cosmvm/neutron/static_files/init.sh b/services/cosmvm/neutron/static_files/init.sh new file mode 100644 index 00000000..0f1a1340 --- /dev/null +++ b/services/cosmvm/neutron/static_files/init.sh @@ -0,0 +1,85 @@ +#!/bin/bash +set -e + +key=${key:-test-key} +password=${password:-clock post desk civil pottery foster expand merit dash seminar song memory figure uniform spice circle try happy obvious trash crime hybrid hood cushion} + +echo $password $key + +BINARY=${BINARY:-neutrond} +BASE_DIR=./data +CHAINID=${CHAINID:-test-1} +STAKEDENOM=${STAKEDENOM:-untrn} +IBCATOMDENOM=${IBCATOMDENOM:-uibcatom} +IBCUSDCDENOM=${IBCUSDCDENOM:-uibcusdc} +CHAIN_DIR="$BASE_DIR/$CHAINID" + +P2PPORT=${P2PPORT:-26656} +RPCPORT=${RPCPORT:-26657} +RESTPORT=${RESTPORT:-1317} +ROSETTA=${ROSETTA:-8081} + +VAL_MNEMONIC_1="clock post desk civil pottery foster expand merit dash seminar song memory figure uniform spice circle try happy obvious trash crime hybrid hood cushion" +VAL_MNEMONIC_2="angry twist harsh drastic left brass behave host shove marriage fall update business leg direct reward object ugly security warm tuna model broccoli choice" +DEMO_MNEMONIC_1="banner spread envelope side kite person disagree path silver will brother under couch edit food venture squirrel civil budget number acquire point work mass" +DEMO_MNEMONIC_2="veteran try aware erosion drink dance decade comic dawn museum release episode original list ability owner size tuition surface ceiling depth seminar capable only" +DEMO_MNEMONIC_3="obscure canal because tomorrow tribe sibling describe satoshi kiwi upgrade bless empty math trend erosion oblige donate label birth chronic hazard ensure wreck shine" +RLY_MNEMONIC_1="alley afraid soup fall idea toss can goose become valve initial strong forward bright dish figure check leopard decide warfare hub unusual join cart" +RLY_MNEMONIC_2="record gift you once hip style during joke field prize dust unique length more pencil transfer quit train device arrive energy sort steak upset" + +# Stop if it is already running +if pgrep -x "$BINARY" >/dev/null; then + echo "Terminating $BINARY..." + killall "$BINARY" +fi + +echo "Removing previous data..." +rm -rf "$CHAIN_DIR" &> /dev/null + +# Add directories for both chains, exit if an error occurs +if ! mkdir -p "$CHAIN_DIR" 2>/dev/null; then + echo "Failed to create chain folder. Aborting..." + exit 1 +fi + +echo "Initializing $CHAINID..." +$BINARY init test --home "$CHAIN_DIR" --chain-id="$CHAINID" + + +echo "Adding genesis accounts..." +$BINARY keys add $key --home "$CHAIN_DIR" --keyring-backend=test --output json > ../../start-scripts/key_seed.json +#echo "$VAL_MNEMONIC_1" | $BINARY keys add $key --home "$CHAIN_DIR" --recover --keyring-backend=test +echo "$VAL_MNEMONIC_2" | $BINARY keys add val2 --home "$CHAIN_DIR" --recover --keyring-backend=test +echo "$DEMO_MNEMONIC_1" | $BINARY keys add demowallet1 --home "$CHAIN_DIR" --recover --keyring-backend=test +echo "$DEMO_MNEMONIC_2" | $BINARY keys add demowallet2 --home "$CHAIN_DIR" --recover --keyring-backend=test +echo "$DEMO_MNEMONIC_3" | $BINARY keys add demowallet3 --home "$CHAIN_DIR" --recover --keyring-backend=test +echo "$RLY_MNEMONIC_1" | $BINARY keys add rly1 --home "$CHAIN_DIR" --recover --keyring-backend=test +echo "$RLY_MNEMONIC_2" | $BINARY keys add rly2 --home "$CHAIN_DIR" --recover --keyring-backend=test + +$BINARY add-genesis-account "$($BINARY --home "$CHAIN_DIR" keys show $key --keyring-backend test -a)" "100000000000000$STAKEDENOM" --home "$CHAIN_DIR" +$BINARY add-genesis-account "$($BINARY --home "$CHAIN_DIR" keys show val2 --keyring-backend test -a)" "100000000000000$STAKEDENOM" --home "$CHAIN_DIR" +$BINARY add-genesis-account "$($BINARY --home "$CHAIN_DIR" keys show demowallet1 --keyring-backend test -a)" "100000000000000$STAKEDENOM,100000000000000$IBCATOMDENOM,100000000000000$IBCUSDCDENOM" --home "$CHAIN_DIR" +$BINARY add-genesis-account "$($BINARY --home "$CHAIN_DIR" keys show demowallet2 --keyring-backend test -a)" "100000000000000$STAKEDENOM,100000000000000$IBCATOMDENOM,100000000000000$IBCUSDCDENOM" --home "$CHAIN_DIR" +$BINARY add-genesis-account "$($BINARY --home "$CHAIN_DIR" keys show demowallet3 --keyring-backend test -a)" "100000000000000$STAKEDENOM,100000000000000$IBCATOMDENOM,100000000000000$IBCUSDCDENOM" --home "$CHAIN_DIR" +$BINARY add-genesis-account "$($BINARY --home "$CHAIN_DIR" keys show rly1 --keyring-backend test -a)" "100000000000000$STAKEDENOM" --home "$CHAIN_DIR" +$BINARY add-genesis-account "$($BINARY --home "$CHAIN_DIR" keys show rly2 --keyring-backend test -a)" "100000000000000$STAKEDENOM" --home "$CHAIN_DIR" + +sed -i -e 's/timeout_commit = "5s"/timeout_commit = "1s"/g' "$CHAIN_DIR/config/config.toml" +sed -i -e 's/timeout_propose = "3s"/timeout_propose = "1s"/g' "$CHAIN_DIR/config/config.toml" +sed -i -e 's/index_all_keys = false/index_all_keys = true/g' "$CHAIN_DIR/config/config.toml" +sed -i -e 's/enable = false/enable = true/g' "$CHAIN_DIR/config/app.toml" +sed -i -e 's/swagger = false/swagger = true/g' "$CHAIN_DIR/config/app.toml" +sed -i -e "s/minimum-gas-prices = \"\"/minimum-gas-prices = \"0.0025$STAKEDENOM,0.0025ibc\/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2\"/g" "$CHAIN_DIR/config/app.toml" +sed -i -e 's/enabled = false/enabled = true/g' "$CHAIN_DIR/config/app.toml" +sed -i -e 's/prometheus-retention-time = 0/prometheus-retention-time = 1000/g' "$CHAIN_DIR/config/app.toml" + +sed -i -e 's#"tcp://0.0.0.0:26656"#"tcp://0.0.0.0:'"$P2PPORT"'"#g' "$CHAIN_DIR/config/config.toml" +sed -i -e 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:'"$RPCPORT"'"#g' "$CHAIN_DIR/config/config.toml" +sed -i -e 's#"tcp://0.0.0.0:1317"#"tcp://0.0.0.0:'"$RESTPORT"'"#g' "$CHAIN_DIR/config/app.toml" +sed -i -e 's#":8080"#":'"$ROSETTA_1"'"#g' "$CHAIN_DIR/config/app.toml" + +GENESIS_FILE="$CHAIN_DIR/config/genesis.json" + +sed -i -e "s/\"denom\": \"stake\",/\"denom\": \"$STAKEDENOM\",/g" "$GENESIS_FILE" +sed -i -e "s/\"mint_denom\": \"stake\",/\"mint_denom\": \"$STAKEDENOM\",/g" "$GENESIS_FILE" +sed -i -e "s/\"bond_denom\": \"stake\"/\"bond_denom\": \"$STAKEDENOM\"/g" "$GENESIS_FILE" diff --git a/services/cosmvm/neutron/static_files/start.sh b/services/cosmvm/neutron/static_files/start.sh new file mode 100644 index 00000000..168fe5f6 --- /dev/null +++ b/services/cosmvm/neutron/static_files/start.sh @@ -0,0 +1,37 @@ +#!/bin/bash +set -e + +key=${key:-test-key} +password=${password:-clock post desk civil pottery foster expand merit dash seminar song memory figure uniform spice circle try happy obvious trash crime hybrid hood cushion} + +BINARY=${BINARY:-neutrond} +BASE_DIR=./data +CHAINID=${CHAINID:-test-1} +GRPCPORT=${GRPCPORT:-9090} +GRPCWEB=${GRPCWEB:-9091} +CHAIN_DIR="$BASE_DIR/$CHAINID" + +RUN_BACKGROUND=${RUN_BACKGROUND:-1} + +echo "Starting $CHAINID in $CHAIN_DIR..." +echo "Creating log file at $CHAIN_DIR/$CHAINID.log" +if [ "$RUN_BACKGROUND" == 1 ]; then + $BINARY start \ + --log_level debug \ + --log_format json \ + --home "$CHAIN_DIR" \ + --pruning=nothing \ + --grpc.address="0.0.0.0:$GRPCPORT" \ + --grpc-web.address="0.0.0.0:$GRPCWEB" \ + --trace > "$CHAIN_DIR/$CHAINID.log" 2>&1 & +else + $BINARY start \ + --log_level debug \ + --log_format json \ + --home "$CHAIN_DIR" \ + --pruning=nothing \ + --grpc.address="0.0.0.0:$GRPCPORT" \ + --grpc-web.address="0.0.0.0:$GRPCWEB" \ + --trace 2>&1 | tee "$CHAIN_DIR/$CHAINID.log" +fi + diff --git a/services/evm/eth/src/node-setup/start-eth-node.star b/services/evm/eth/src/node-setup/start-eth-node.star index aeda32e6..06d2b60c 100644 --- a/services/evm/eth/src/node-setup/start-eth-node.star +++ b/services/evm/eth/src/node-setup/start-eth-node.star @@ -8,7 +8,7 @@ network_keys_and_public_address = constants.NETWORK_PORT_KEYS_AND_IP_ADDRESS # Spins Up the ETH Node def start_eth_node(plan,args): - eth_contstants = constants.ETH_NODE_CLIENT + eth_constants = constants.ETH_NODE_CLIENT args_with_right_defaults = input_parser.get_args_with_default_values(args) num_participants = len(args_with_right_defaults.participants) network_params = args_with_right_defaults.network_params @@ -19,13 +19,13 @@ def start_eth_node(plan,args): return struct( service_name = all_participants[0].el_client_context.service_name, - network_name= eth_contstants.network_name, - network = eth_contstants.network, - nid = eth_contstants.nid, + network_name= eth_constants.network_name, + network = eth_constants.network, + nid = eth_constants.nid, endpoint = "http://%s" % network_address, endpoint_public = "http://", - keystore_path = eth_contstants.keystore_path, - keypassword = eth_contstants.keypassword + keystore_path = eth_constants.keystore_path, + keypassword = eth_constants.keypassword )