diff --git a/.envrc.example b/.envrc.example new file mode 100644 index 0000000..5307aee --- /dev/null +++ b/.envrc.example @@ -0,0 +1,2 @@ +use flake +export DIRENV_ACTIVE=1 # force direnv to always activate by adding a dummy environment variable diff --git a/docs/sample_pystarport_configs/chain-main_sample.jsonnet b/docs/sample_pystarport_configs/chain-main_sample.jsonnet new file mode 100644 index 0000000..3e25254 --- /dev/null +++ b/docs/sample_pystarport_configs/chain-main_sample.jsonnet @@ -0,0 +1,59 @@ +{ + 'chainmain_777-1': { // Cosmos chain ID: chainmain_777-1 + cmd: 'chain-maind', + 'start-flags': '--trace', + + validators: [ // blockchain validators config + { + coins: '200000000000000000basetcro', + staked: '100000000000000000basetcro', + mnemonic: 'elbow flight coast travel move behind sister tell avocado road wait above', + base_port: 26750, + }, + { + coins: '200000000000000000basetcro', + staked: '100000000000000000basetcro', + mnemonic: 'nasty large defy garage violin casual alarm blue marble industry infant inside', + base_port: 26760, + }, + ], + + accounts: [ + { + name: 'alice', + coins: '100000000000000000000basetcro', + mnemonic: 'super develop desert oak load field ring jazz tray spray found novel', + }, + { + name: 'bob', + coins: '100000000000000000000basetcro', + mnemonic: 'loyal legend allow glow wheel heavy pretty example tell peasant myself garlic battle bachelor buddy stand true grit manual letter wire alone polar glove', + }, + { + name: 'relayer', // account name must be "relayer" for IBC to work in pystarport + coins: '10000000000000000000000000basetcro', + mnemonic: 'summer account another open charge item reason double green winner six genuine glue daughter index pause bulb rival adult boss enlist bench oxygen asthma', + }, + ], + + config: { // patch config.toml + consensus: { + timeout_commit: '5s', + create_empty_blocks_interval: '5s', + }, + }, + + 'app-config': { // patch app.toml + 'minimum-gas-prices': '0.025basetcro', + }, + + genesis: { // patch genesis.json + consensus_params: { + block: { + max_bytes: '500000', + max_gas: '81500000', + }, + }, + }, + }, +} diff --git a/docs/sample_pystarport_configs/chain-main_sample.yaml b/docs/sample_pystarport_configs/chain-main_sample.yaml new file mode 100644 index 0000000..41e7194 --- /dev/null +++ b/docs/sample_pystarport_configs/chain-main_sample.yaml @@ -0,0 +1,38 @@ +chainmain_777-1: # Cosmos chain ID: chainmain_777-1 + cmd: chain-maind + start-flags: "--trace" + + validators: # blockchain validators config + - base_port: 26750 + coins: 200000000000000000basetcro + mnemonic: elbow flight coast travel move behind sister tell avocado road wait above + staked: 100000000000000000basetcro + - base_port: 26760 + coins: 200000000000000000basetcro + mnemonic: nasty large defy garage violin casual alarm blue marble industry infant inside + staked: 100000000000000000basetcro + + accounts: + - name: alice + coins: 10000000000000000000000000basetcro + mnemonic: super develop desert oak load field ring jazz tray spray found novel + - name: bob + coins: 10000000000000000000000000basetcro + mnemonic: loyal legend allow glow wheel heavy pretty example tell peasant myself garlic battle bachelor buddy stand true grit manual letter wire alone polar glove + - name: relayer # account name must be "relayer" for IBC to work in pystarport + coins: 10000000000000000000000000basetcro + mnemonic: summer account another open charge item reason double green winner six genuine glue daughter index pause bulb rival adult boss enlist bench oxygen asthma + + config: # patch config.toml + consensus: + create_empty_blocks_interval: 5s + timeout_commit: 5s + + app-config: # patch app.toml + minimum-gas-prices: 0.025basetcro + + genesis: # patch genesis.json + consensus_params: + block: + max_bytes: "500000" + max_gas: "81500000" diff --git a/docs/sample_pystarport_configs/cronos_sample.jsonnet b/docs/sample_pystarport_configs/cronos_sample.jsonnet new file mode 100644 index 0000000..4dbdc77 --- /dev/null +++ b/docs/sample_pystarport_configs/cronos_sample.jsonnet @@ -0,0 +1,72 @@ +{ + 'cronos_777-1': { // Cosmos chain ID: cronos_777-1; EVM chain ID: 777 + cmd: 'cronosd', + 'start-flags': '--trace', + + validators: [ // blockchain validators config + { + coins: '200000000000000000000basetcro, 2000000000000000000stake', + staked: '1000000000000000000stake', + gas_prices: '10000000000000basetcro', + mnemonic: 'elbow flight coast travel move behind sister tell avocado road wait above', + base_port: 26650, + }, + { + coins: '200000000000000000000basetcro, 2000000000000000000stake', + staked: '1000000000000000000stake', + gas_prices: '10000000000000basetcro', + mnemonic: 'nasty large defy garage violin casual alarm blue marble industry infant inside', + base_port: 26660, + }, + ], + + accounts: [ + { + name: 'alice', + coins: '100000000000000000000basetcro', + mnemonic: 'super develop desert oak load field ring jazz tray spray found novel', + }, + { + name: 'bob', + coins: '100000000000000000000basetcro', + mnemonic: 'loyal legend allow glow wheel heavy pretty example tell peasant myself garlic battle bachelor buddy stand true grit manual letter wire alone polar glove', + }, + { + name: 'relayer', + coins: '100000000000000000000basetcro', + mnemonic: 'summer account another open charge item reason double green winner six genuine glue daughter index pause bulb rival adult boss enlist bench oxygen asthma', + } + ], + + config: { // patch config.toml + consensus: { + timeout_commit: '5s', + create_empty_blocks_interval: '5s', + }, + }, + + 'app-config': { // patch app.toml + 'minimum-gas-prices': '5000000000000basetcro', + 'json-rpc': { + address: '0.0.0.0:{EVMRPC_PORT}', + 'ws-address': '0.0.0.0:{EVMRPC_PORT_WS}', + }, + }, + + genesis: { // patch genesis.json + consensus: { + params: { + block: { + max_bytes: '1048576', + max_gas: '81500000', + }, + }, + }, + evm: { + params: { + evm_denom: 'basetcro', + }, + }, + }, + }, +} diff --git a/docs/sample_pystarport_configs/cronos_sample.yaml b/docs/sample_pystarport_configs/cronos_sample.yaml new file mode 100644 index 0000000..9c92f7e --- /dev/null +++ b/docs/sample_pystarport_configs/cronos_sample.yaml @@ -0,0 +1,47 @@ +cronos_777-1: # Cosmos chain ID: cronos_777-1; EVM chain ID: 777 + cmd: cronosd + start-flags: "--trace" + + validators: # blockchain validators config + - base_port: 26650 + coins: 200000000000000000000basetcro, 2000000000000000000stake + gas_prices: 10000000000000basetcro + mnemonic: elbow flight coast travel move behind sister tell avocado road wait above + staked: 1000000000000000000stake + - base_port: 26660 + coins: 200000000000000000000basetcro, 2000000000000000000stake + gas_prices: 10000000000000basetcro + mnemonic: nasty large defy garage violin casual alarm blue marble industry infant inside + staked: 1000000000000000000stake + + accounts: + - name: alice + coins: 10000000000000000000000000basetcro + mnemonic: super develop desert oak load field ring jazz tray spray found novel + - name: bob + coins: 10000000000000000000000000basetcro + mnemonic: loyal legend allow glow wheel heavy pretty example tell peasant myself garlic battle bachelor buddy stand true grit manual letter wire alone polar glove + - name: relayer # account name must be "relayer" for IBC to work in pystarport + coins: 10000000000000000000000000basetcro + mnemonic: summer account another open charge item reason double green winner six genuine glue daughter index pause bulb rival adult boss enlist bench oxygen asthma + + config: # patch config.toml + consensus: + create_empty_blocks_interval: 5s + timeout_commit: 5s + + app-config: # patch app.toml + json-rpc: + address: 0.0.0.0:{EVMRPC_PORT} + ws-address: 0.0.0.0:{EVMRPC_PORT_WS} + minimum-gas-prices: 5000000000000basetcro + + genesis: # patch genesis.json + consensus: + params: + block: + max_bytes: "1048576" + max_gas: "81500000" + evm: + params: + evm_denom: basetcro diff --git a/docs/sample_pystarport_configs/ibc_sample.jsonnet b/docs/sample_pystarport_configs/ibc_sample.jsonnet new file mode 100644 index 0000000..d240f64 --- /dev/null +++ b/docs/sample_pystarport_configs/ibc_sample.jsonnet @@ -0,0 +1,49 @@ +local chainmain_devnet = import 'chain-main_sample.jsonnet'; +local cronos_devnet = import 'cronos_sample.jsonnet'; + +{ + 'cronos_777-1': cronos_devnet['cronos_777-1'] { 'coin-type': 60 }, + 'chainmain_777-1': chainmain_devnet['chainmain_777-1'] { 'coin-type': 1 }, + relayer: { + // https://hermes.informal.systems/documentation/configuration/index.html + chains: [ + { + id: 'chainmain_777-1', // id needs to match the chain ID + account_prefix: 'tcro', + default_gas: 1000000, + max_gas: 3000000, + gas_multiplier: 1.1, + address_type: { + derivation: 'cosmos', + }, + gas_price: { + price: 0.025, + denom: 'basetcro', + }, + }, + { + id: 'cronos_777-1', // id needs to match the chain ID + account_prefix: 'tcrc', + default_gas: 600000, + max_gas: 3600000, + gas_multiplier: 1.1, + address_type: { + derivation: 'ethermint', + proto_type: { + pk_type: '/ethermint.crypto.v1.ethsecp256k1.PubKey', + }, + }, + gas_price: { + price: 100000000000000, + denom: 'basetcro', + }, + extension_options: [ + { + type: 'ethermint_dynamic_fee', + value: '500000000000', + }, + ], + }, + ], + }, +} diff --git a/docs/sample_pystarport_configs/ibc_sample.yaml b/docs/sample_pystarport_configs/ibc_sample.yaml new file mode 100644 index 0000000..5aa6105 --- /dev/null +++ b/docs/sample_pystarport_configs/ibc_sample.yaml @@ -0,0 +1,116 @@ +chainmain_777-1: # Cosmos chain ID: chainmain_777-1 + cmd: chain-maind + start-flags: "--trace" + coin-type: 1 + + validators: # blockchain validators config + - base_port: 26750 + coins: 200000000000000000basetcro + mnemonic: elbow flight coast travel move behind sister tell avocado road wait above + staked: 100000000000000000basetcro + - base_port: 26760 + coins: 200000000000000000basetcro + mnemonic: nasty large defy garage violin casual alarm blue marble industry infant inside + staked: 100000000000000000basetcro + + accounts: + - name: alice + coins: 10000000000000000000000000basetcro + mnemonic: super develop desert oak load field ring jazz tray spray found novel + - name: bob + coins: 10000000000000000000000000basetcro + mnemonic: loyal legend allow glow wheel heavy pretty example tell peasant myself garlic battle bachelor buddy stand true grit manual letter wire alone polar glove + - name: relayer # account name must be "relayer" for IBC to work in pystarport + coins: 10000000000000000000000000basetcro + mnemonic: summer account another open charge item reason double green winner six genuine glue daughter index pause bulb rival adult boss enlist bench oxygen asthma + + config: # patch config.toml + consensus: + create_empty_blocks_interval: 5s + timeout_commit: 5s + + app-config: # patch app.toml + minimum-gas-prices: 0.025basetcro + + genesis: # patch genesis.json + consensus_params: + block: + max_bytes: "500000" + max_gas: "81500000" + +cronos_777-1: # Cosmos chain ID: cronos_777-1; EVM chain ID: 777 + cmd: cronosd + start-flags: "--trace" + coin-type: 60 + + validators: # blockchain validators config + - base_port: 26650 + coins: 200000000000000000000basetcro, 2000000000000000000stake + gas_prices: 10000000000000basetcro + mnemonic: elbow flight coast travel move behind sister tell avocado road wait above + staked: 1000000000000000000stake + - base_port: 26660 + coins: 200000000000000000000basetcro, 2000000000000000000stake + gas_prices: 10000000000000basetcro + mnemonic: nasty large defy garage violin casual alarm blue marble industry infant inside + staked: 1000000000000000000stake + + accounts: + - name: alice + coins: 10000000000000000000000000basetcro + mnemonic: super develop desert oak load field ring jazz tray spray found novel + - name: bob + coins: 10000000000000000000000000basetcro + mnemonic: loyal legend allow glow wheel heavy pretty example tell peasant myself garlic battle bachelor buddy stand true grit manual letter wire alone polar glove + - name: relayer # account name must be "relayer" for IBC to work in pystarport + coins: 10000000000000000000000000basetcro + mnemonic: summer account another open charge item reason double green winner six genuine glue daughter index pause bulb rival adult boss enlist bench oxygen asthma + + config: # patch config.toml + consensus: + create_empty_blocks_interval: 5s + timeout_commit: 5s + + app-config: # patch app.toml + json-rpc: + address: 0.0.0.0:{EVMRPC_PORT} + ws-address: 0.0.0.0:{EVMRPC_PORT_WS} + minimum-gas-prices: 5000000000000basetcro + + genesis: # patch genesis.json + consensus: + params: + block: + max_bytes: "1048576" + max_gas: "81500000" + evm: + params: + evm_denom: basetcro + +relayer: # refer here (https://hermes.informal.systems/documentation/configuration/description.html) for more configs + chains: + - id: chainmain_777-1 # id needs to match the chain ID + account_prefix: tcro + default_gas: 1000000 + max_gas: 3000000 + gas_multiplier: 1.1 + address_type: + derivation: cosmos + gas_price: + price: 0.025 + denom: basetcro + - id: cronos_777-1 # id needs to match the chain ID + account_prefix: tcrc + default_gas: 600000 + max_gas: 3600000 + gas_multiplier: 1.1 + address_type: + derivation: ethermint + proto_type: + pk_type: /ethermint.crypto.v1.ethsecp256k1.PubKey + gas_price: + price: 100000000000000 + denom: "basetcro" + extension_options: + - type: ethermint_dynamic_fee + value: "500000000000" diff --git a/docs/setup.md b/docs/setup.md new file mode 100644 index 0000000..61ec612 --- /dev/null +++ b/docs/setup.md @@ -0,0 +1,28 @@ +# Project Setup + +1. Copy `.envrc.example` to `.envrc`. +2. Install [nix](https://nixos.org/download/). +3. Install [direnv](https://direnv.net/) and [nix-direnv](https://github.com/nix-community/nix-direnv). +4. Run `direnv allow` at project root. This is to automatically load the environment when you `cd` into the project directory in the terminal in the future. +5. Run `which python` to verify that the Python interpreter is from the nix environment. + + ```shell + $ which python + /nix/store/9l232zbyi3nisqn9s3li4imyv37753vc-python3-3.11.9-env/bin/python + ``` + + Path should look similar to the above from `/nix/store`. This confirms that you are using the correct Python interpreter. + +6. Run `python -mpytest` to execute all tests. + +If you are able to run all tests, you are ready to go! + +## VS Code + +1. For intellisense in VS Code, add result of `which python` to your `.vscode/settings.json`: + + ```json + { + "python.defaultInterpreterPath": "output of `which python`" + } + ``` diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..6be4e7c --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,154 @@ +# Usage + +## Available Commands + +```shell +pystarport -c +``` + +Commands below are useful for starting a blockchain locally and managing it: + +- `pystarport init`: preparation to start a local blockchain based on the provided configuration file. +- `pystarport start`: start the local blockchain. +- `pystarport serve`: combination of `pystarport init` and `pystarport start`. +- `pystarport supervisorctl`: use the embedded [supervisor](http://supervisord.org/) to manage processes of multiple blockchain nodes and the relayer. + +You can append `--help` to any command for more information. + +## The Configuration File + +The configuration file is a crucial part to set up the local blockchain environment. It can be in `.yaml` or `.jsonnet` format. (`.jsonnet` format is preferred for its flexibility and ability to generate complex configurations programmatically). Some examples of configuration files for starting Cronos or Cronos POS blockchain are provided in the `docs/sample_pystarport_configs` directory. + +### Configuration File Structure for Single Blockchain + +#### `chain_id` + +The unique identifier for the blockchain. For example, `cronos_777-1`. + +In this case, the Cosmos chain ID is `cronos_777-1`, and the EVM chain ID is `777`. + +#### `cmd` + +The command to start the blockchain node (e.g., `chain-maind` or `cronosd`), make sure they are present in the `PATH`. + +#### `start-flags` + +Additional flags to pass to the command when starting the node. + +#### `validators` + +A list of validator configurations, each containing: + +- `coins`: the amount and denomination of coins the validator has. +- `staked`: the amount and denomination of coins the validator has staked. +- `gas_prices`: the gas prices for the validator's transactions. (Only required for EVM chains) +- `mnemonic`: the mnemonic phrase for the validator's key. +- `base_port`: the base port for the validator's RPC server. +- (optional) `moniker`: human readable name for the node (default is node1, node2, etc.) + +For a full node configuration, you can omit the `coins`, `staked`, `gas_prices`, and `mnemonic` fields. + +```jsonnet +validators: [ + { + moniker: "fullnode_jsonnet_example", + base_port: 26780 + } +] +``` + +#### `accounts` + +A list of genesis account configurations with coins, each containing: + +- `name`: the name of the genesis account imported to local keyring. +- `coins`: the amount of coins the genesis account has. +- `address`: the address of the genesis account. (If this field exists, `mnemonic` field will be ignored. This field can be left out, if `mnemonic` is provided) +- `mnemonic`: the mnemonic phrase for the genesis account. + +#### `config` and `app-config` + +`config` section patches `config.toml` and `app-config` section patches `app.toml`. + +E.g. to use this config in the `app.toml` for the local blockchain + +```toml +minimum-gas-prices="0.025basetcro" + +[json-rpc] +block-range-cap = 10000 +``` + +Add section below to the config yaml file + +```yaml +app-config: + minimum-gas-prices: "0.025basetcro" + json-rpc: + block-range-cap: 10000 +``` + +or config jsonnet file + +```jsonnet +app-config: { + minimum-gas-prices: "0.025basetcro", + json-rpc: { + block-range-cap: 10000 + } +} +``` + +By default, all validators have the same `config.toml` and `app.toml`. If you would like to customize these files for each validator, you can do so by specifying the `config` and `app-config` sections for each validator in the configuration file. + +```jsonnet +validators: [ + { + moniker: "validator_jsonnet_example", + coins: '200000000000000000basetcro', + staked: '100000000000000000basetcro', + mnemonic: "valid mnemonic", + base_port: 26750, + // this validator requires different minimum gas prices + 'app-config': { + minimum-gas-prices: "0.05basetcro" + }, + }, + 'app-config': { + minimum-gas-prices: "0.025basetcro", + } +] +``` + +#### `genesis` + +`genesis` section patches the `genesis.json` file. Its syntax is similar to the `config` and `app-config` sections. +**Note:** The genesis is the initial state of the entire local blockchain, hence it does not allow customization for each validator like the `config` and `app-config` sections. + + +### Configuration File Structure for Blockchains with IBC + +The configuration file for blockchains with IBC (Inter-Blockchain Communication) is similar to that of single blockchains, but it includes the additional section for relayer configurations. And you will also see the `.jsonnet` format is simpler than the `.yaml` format. For more relayer configurations, please refer to the [Hermes documentation](https://hermes.informal.systems/documentation/configuration/description.html). + +## Start Local Blockchain + +### Single Blockchain + +```shell +# make sure is in your PATH +pystarport start --config= +``` + +### Start Blockchains with IBC + +```shell +# make sure is in your PATH +# make sure hermes is in your PATH +pystarport start --config= + +# wait for blockchains to reach at lease block height 2, then create an IBC channel +hermes create channel [OPTIONS] --a-chain --b-chain --a-port --b-port --new-client-connection + +# wait for channels to be created successfully, then start the relayer +supervisorctl -c /path/to/supervisor/task.ini start relayer-demo +```