Skip to content

Commit

Permalink
refactor: merge mainnet and localnet config.json files and remove u…
Browse files Browse the repository at this point in the history
…nnecessary keys (#20)

* chore: add `accounts` key to mainnet config.json

* docs: improve docs

* refactor: remove unnecessary configs and merge configs

* fix: comments typo

* fix: set `DefaultNodeHome` correctly

* chore: rename and remove keys from config

* docs: add genesis docs

* refactor: make code conform more to what ignite cli scaffolds
  • Loading branch information
AaronCQL committed Aug 19, 2023
1 parent 94f9444 commit 906b2d5
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 252 deletions.
66 changes: 4 additions & 62 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,72 +27,23 @@ ifeq ($(JQ),)
endif

# read feather config
FEATH_CONFIG := $(CURDIR)/config/config.json

FEATH_CONFIG := $(CURDIR)/config/mainnet/config.json

# these keys must match config/mainnet/config.json
# these keys must match those in config.json
KEY_APP_NAME=app_name
KEY_BOND_DENOM=bond_denom
KEY_APP_BINARY_NAME=app_binary_name
KEY_ACC_ADDR_PREFIX=account_address_prefix
KEY_ACC_PUBKEY_PREFIX=account_pubkey_prefix
KEY_VALIDATOR_ADDRESS_PREFIX=validator_address_prefix
KEY_VALIDATOR_PUBKEY_PREFIX=validator_pubkey_prefix
KEY_CONS_NODE_ADDR_PREFIX=consensus_node_address_prefix
KEY_CONS_NODE_PUBKEY_PREFIX=consensus_node_pubkey_prefix

# check that required keys are defined in config.json
HAS_APP_NAME := $(shell jq 'has("$(KEY_APP_NAME)")' $(FEATH_CONFIG))
HAS_BOND_DENOM := $(shell jq 'has("$(KEY_BOND_DENOM)")' $(FEATH_CONFIG))
HAS_APP_BINARY_NAME := $(shell jq 'has("$(KEY_APP_BINARY_NAME)")' $(FEATH_CONFIG))
HAS_ACC_ADDR_PREFIX := $(shell jq 'has("$(KEY_ACC_ADDR_PREFIX)")' $(FEATH_CONFIG))
HAS_ACC_PUBKEY_PREFIX := $(shell jq 'has("$(KEY_ACC_PUBKEY_PREFIX)")' $(FEATH_CONFIG))
HAS_VALIDATOR_ADDRESS_PREFIX := $(shell jq 'has("$(KEY_VALIDATOR_ADDRESS_PREFIX)")' $(FEATH_CONFIG))
HAS_VALIDATOR_PUBKEY_PREFIX := $(shell jq 'has("$(KEY_VALIDATOR_PUBKEY_PREFIX)")' $(FEATH_CONFIG))
HAS_CONS_NODE_ADDR_PREFIX := $(shell jq 'has("$(KEY_CONS_NODE_ADDR_PREFIX)")' $(FEATH_CONFIG))
HAS_CONS_NODE_PUBKEY_PREFIX := $(shell jq 'has("$(KEY_CONS_NODE_PUBKEY_PREFIX)")' $(FEATH_CONFIG))

ifeq ($(HAS_APP_NAME),false)
$(error "$(FEATH_CONFIG) does not have key $(KEY_APP_NAME)")
endif
ifeq ($(HAS_BOND_DENOM),false)
$(error "$(FEATH_CONFIG) does not have key $(KEY_BOND_DENOM)")
endif
ifeq ($(HAS_APP_BINARY_NAME),false)
$(error "$(FEATH_CONFIG) does not have key $(KEY_APP_BINARY_NAME)")
endif
ifeq ($(HAS_ACC_ADDR_PREFIX),false)
$(error "$(FEATH_CONFIG) does not have key $(KEY_ACC_ADDR_PREFIX)")
endif
ifeq ($(HAS_ACC_PUBKEY_PREFIX),false)
$(error "$(FEATH_CONFIG) does not have key $(KEY_ACC_PUBKEY_PREFIX)")
endif
ifeq ($(HAS_VALIDATOR_ADDRESS_PREFIX),false)
$(error "$(FEATH_CONFIG) does not have key $(KEY_VALIDATOR_ADDRESS_PREFIX)")
endif
ifeq ($(HAS_VALIDATOR_PUBKEY_PREFIX),false)
$(error "$(FEATH_CONFIG) does not have key $(KEY_VALIDATOR_PUBKEY_PREFIX)")
endif
ifeq ($(HAS_CONS_NODE_ADDR_PREFIX),false)
$(error "$(FEATH_CONFIG) does not have key $(KEY_CONS_NODE_ADDR_PREFIX)")
endif
ifeq ($(HAS_CONS_NODE_PUBKEY_PREFIX),false)
$(error "$(FEATH_CONFIG) does not have key $(KEY_CONS_NODE_PUBKEY_PREFIX)")
endif

# retrieve key values, strip double quotes
FEATH_CONFIG_APP_NAME := $(patsubst "%",%,$(shell jq '.$(KEY_APP_NAME)' $(FEATH_CONFIG)))
FEATH_CONFIG_BOND_DENOM := $(patsubst "%",%,$(shell jq '.$(KEY_BOND_DENOM)' $(FEATH_CONFIG)))
FEATH_CONFIG_APP_BINARY_NAME := $(patsubst "%",%,$(shell jq '.$(KEY_APP_BINARY_NAME)' $(FEATH_CONFIG)))
FEATH_CONFIG_ACC_ADDR_PREFIX := $(patsubst "%",%,$(shell jq '.$(KEY_ACC_ADDR_PREFIX)' $(FEATH_CONFIG)))
FEATH_CONFIG_ACC_PUBKEY_PREFIX := $(patsubst "%",%,$(shell jq '.$(KEY_ACC_PUBKEY_PREFIX)' $(FEATH_CONFIG)))
FEATH_CONFIG_VALIDATOR_ADDRESS_PREFIX := $(patsubst "%",%,$(shell jq '.$(KEY_VALIDATOR_ADDRESS_PREFIX)' $(FEATH_CONFIG)))
FEATH_CONFIG_VALIDATOR_PUBKEY_PREFIX := $(patsubst "%",%,$(shell jq '.$(KEY_VALIDATOR_PUBKEY_PREFIX)' $(FEATH_CONFIG)))
FEATH_CONFIG_CONS_NODE_ADDR_PREFIX := $(patsubst "%",%,$(shell jq '.$(KEY_CONS_NODE_ADDR_PREFIX)' $(FEATH_CONFIG)))
FEATH_CONFIG_CONS_NODE_PUBKEY_PREFIX := $(patsubst "%",%,$(shell jq '.$(KEY_CONS_NODE_PUBKEY_PREFIX)' $(FEATH_CONFIG)))
FEATH_CONFIG_APP_BINARY_NAME := $(FEATH_CONFIG_APP_NAME)d

# process build tags

build_tags = netgo
ifeq ($(LEDGER_ENABLED),true)
ifeq ($(OS),Windows_NT)
Expand Down Expand Up @@ -129,20 +80,11 @@ comma := ,
build_tags_comma_sep := $(subst $(empty),$(comma),$(build_tags))

# process linker flags

ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=$(FEATH_CONFIG_APP_NAME) \
-X github.com/cosmos/cosmos-sdk/version.AppName=$(FEATH_CONFIG_APP_BINARY_NAME) \
-X github.com/cosmos/cosmos-sdk/version.Version=$(FEATHER_CORE_VERSION) \
-X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" \
-X github.com/terra-money/feather-core/app.AppName=$(FEATH_CONFIG_APP_NAME) \
-X github.com/terra-money/feather-core/app.AccountAddressPrefix=$(FEATH_CONFIG_ACC_ADDR_PREFIX) \
-X github.com/terra-money/feather-core/app.AccountPubKeyPrefix=$(FEATH_CONFIG_ACC_PUBKEY_PREFIX) \
-X github.com/terra-money/feather-core/app.ValidatorAddressPrefix=$(FEATH_CONFIG_VALIDATOR_ADDRESS_PREFIX) \
-X github.com/terra-money/feather-core/app.ValidatorPubKeyPrefix=$(FEATH_CONFIG_VALIDATOR_PUBKEY_PREFIX) \
-X github.com/terra-money/feather-core/app.ConsensusNodeAddressPrefix=$(FEATH_CONFIG_CONS_NODE_ADDR_PREFIX) \
-X github.com/terra-money/feather-core/app.ConsensusNodePubKeyPrefix=$(FEATH_CONFIG_CONS_NODE_PUBKEY_PREFIX) \
-X github.com/terra-money/feather-core/app.BondDenom=$(FEATH_CONFIG_BOND_DENOM)
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)"

ifeq ($(WITH_CLEVELDB),yes)
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb
Expand Down
149 changes: 50 additions & 99 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
- [Installing](#installing)
- [Developing](#developing)
- [Configuring](#configuring)
- [For Development](#for-development)
- [For Production](#for-production)
- [Genesis Validator Delegations](#genesis-validator-delegations)
- [Genesis Account Balances](#genesis-account-balances)
- [Genesis Coins Total Supply](#genesis-coins-total-supply)
- [Publishing](#publishing)
- [Approving Join Requests](#approving-join-requests)
- [Interfaces](#interfaces)
Expand Down Expand Up @@ -42,82 +43,29 @@ feather dev build
Check for correctness by running chain simulations:

```bash
# Run in repo root
# Run in repo root:
feather dev simulate
```

Initialize configs to start the chain (for local testing):
Initialize and run a localnet with a single local validator for testing purposes:

```bash
# Run in repo root
feather dev sandbox init
# Run in repo root:
feather dev sandbox serve

# Start the chain (your binary name may differ)
feather-cored start
# OR, if you prefer to be explicit:
feather dev sandbox init # initialize all genesis files
feather-cored start # start the localnet (your built binary name may differ)
```

## Configuring

### For Development

Configure the `config/localnet/config.json` file if you want to test run your chain before deploying to production with Feather.

```js
{
// Naming convention: `[-a-zA-Z0-9]{3,47}`.
"chain_id": "localnet-1",
// List of genesis accounts, with their bank balances at genesis.
"accounts": [
{
"name": "alice",
"coins": [
{
"denom": "token",
"amount": "20000"
},
{
"denom": "stake",
"amount": "200000000"
}
]
},
{
"name": "bob",
"coins": [
{
"denom": "token",
"amount": "10000"
},
{
"denom": "stake",
"amount": "100000000"
}
]
}
],
// List of genesis validators, with their staked coins at genesis.
"validators": [
{
"name": "alice",
"bonded": {
"denom": "stake",
"amount": "100000000"
}
}
]
}
```

### For Production

Configure the `config/mainnet/config.json` if you would like to do any of the following:
Edit the `config/config.json` file if you would like to do any of the following:

1. Change the default bond denom of the chain
2. Change the name of the chain and chain binary
2. Change the chain ID
3. Change the genesis account balances
4. Change the address prefixes of user accounts, validator accounts or consensus accounts
5. Change parameters from the `x/staking` module when the chain is deployed by Feather
6. Configure the LCD/RPC/Prometheus endpoints when the chain is deployed by Feather
4. Change the address prefixes of user accounts, validator accounts, and consensus accounts

```js
{
Expand All @@ -127,15 +75,8 @@ Configure the `config/mainnet/config.json` if you would like to do any of the fo
"chain_id": "feather-1",
// Human readable name of the chain.
"app_name": "feather-core",
// Metadata registered in the cosmos sdk package (typically `app_name` suffixed with "d").
"app_binary_name": "feather-cored",
// Address prefixes for user, validator, and consensus accounts.
"account_address_prefix": "pfeath",
"account_pubkey_prefix": "pfeathpub",
"validator_address_prefix": "pfeathvaloper",
"validator_pubkey_prefix": "pfeathvaloperpub",
"consensus_node_address_prefix": "pfeathvalcons",
"consensus_node_pubkey_prefix": "pfeathvalconspub",
// Prefix for all addresses on the chain.
"address_prefix": "pfeath",
// Staking bond denominator (i.e. coin denom used for staking).
"bond_denom": "stake",
// Amount of `bond_denom` used for staking at genesis.
Expand All @@ -145,11 +86,9 @@ Configure the `config/mainnet/config.json` if you would like to do any of the fo
"unbonding_time": "1814400s",
// Max number of validators the chain supports.
"max_validators": 130,
"max_entries": 7,
// Minimum commission rate for validators.
// Minimum commission rate for validators. Must be a number between 0 and 1.
"min_commission_rate": "0",
// List of genesis accounts, with their bank balances at genesis.
// Unlike the `accounts` in `config/localnet/config.json`, the `name` field is replaced with the actual `address`.
// List of genesis accounts, with their balances at genesis.
"accounts": [
{
"address": "pfeath1...aaa",
Expand All @@ -165,32 +104,44 @@ Configure the `config/mainnet/config.json` if you would like to do any of the fo
]
}
],
// Whether to start the LCD server with the chain.
"lcd_enabled": true,
// Exposes a swagger page documenting exposed API endpoints at IP:<lcd_port>.
"lcd_swagger_enabled": true,
// Configurable LCD server port.
"lcd_port": 1317,
// Enable this if querying the blockchain from a CORS-enabled app, like web browsers.
"lcd_enable_unsafe_cors": false,
// Whether to start the RPC server with the chain.
"rpc_enabled": true,
// Configurable RPC server port.
"rpc_port": 26657,
// Whether to enable Prometheus metrics.
"prometheus_enabled": true,
// Configurable Prometheus port.
"prometheus_port": 26660
}
```

The total supply of a coin during chain genesis is the sum of the following:
### Genesis Validator Delegations

At genesis, all validators will have an initial *self-delegation* of exactly `1000000` of the `bond_denom` (ie. `stake`). This is to satisfy Cosmos SDK's requirement of having at least one validator with a total delegation of at least `1000000` of the `bond_denom` during chain genesis.

Additionally, all `bond_supply` (owned by the address of the chain deployer) will be split according to the stake distribution setting specified and delegated to genesis validators. There are currently two stake distribution settings:

1. `equal`: All genesis validators receive an equal amount of delegations (ie. $\frac{\texttt{bond\_supply}}{\texttt{num\_genesis\_validators}}$) from the chain deployer
2. `terravp`: All validators receive delegations proportional to the validator's voting power in the Terra chain from the chain deployer
- A validator that has no voting power in the Terra chain will thus NOT receive any delegations from the chain deployer

In summary, the total delegation or voting power of a validator at chain genesis when using the `equal` stake distribution strategy is:

$$
1000000 + \left( \frac{\texttt{bond\_supply}}{\texttt{num\_genesis\_validators}}\right)
$$

And when using the `terravp` stake distribution strategy:

$$
1000000 + \left( {\texttt{bond\_supply}} \times \frac{\texttt{validator\_voting\_power}}{\texttt{total\_voting\_power}} \right)
$$

### Genesis Account Balances

The `accounts` array in `config.json` specifies the genesis accounts and their balances at chain genesis. These balances are **in addition** of the `bond_supply` field or any validator's self-delegations. In other words, a chain deployer can have a `bond_supply` of `1000000000` and still have an additional genesis account with a balance of `5000000000` of the `bond_denom` (ie. `stake`) specified, meaning they will own a total of `6000000000` of the `bond_denom` at chain genesis. Likewise, a validator will own a total of `1000000` of the `bond_denom` (used for self-delegation) and whatever is specified in the `accounts` array.

### Genesis Coins Total Supply

The total supply of a coin at chain genesis is the sum of the following:

1. The `bond_supply` field
2. The sum of the `amount` fields of the `accounts` array
3. If the coin is the `bond_denom`, the number of validators multiplied by `1000000` (the minimum amount of `bond_denom` required for a validator's self-delegation)
1. The sum of the `amount` fields of the `accounts` array whose `denom` field matches the coin's denom
2. If the coin is the `bond_denom`, the `bond_supply` field
3. If the coin is the `bond_denom`, the number of genesis validators multiplied by `1000000` (the minimum amount of `bond_denom` required for a validator's self-delegation)

In the example `config.json` above, assuming we have exactly 5 validators, the total supply of `stake` is `5005000000` and the total supply of `token` is `3000000000` at chain genesis.
In the example `config.json` above, assuming we have exactly 8 validators, the total supply of `stake` is `5008000000` and the total supply of `token` is `3000000000` at chain genesis.

## Publishing

Expand Down
31 changes: 18 additions & 13 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ import (

"github.com/terra-money/feather-core/app/openapiconsole"
appparams "github.com/terra-money/feather-core/app/params"
cfg "github.com/terra-money/feather-core/config"
"github.com/terra-money/feather-core/docs"
feather "github.com/terra-money/feather-core/x/feather"
FeatherKeeper "github.com/terra-money/feather-core/x/feather/keeper"
Expand All @@ -162,17 +163,12 @@ import (
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
)

// DO NOT change the names of these variables!
// DO NOT change the names of these variables! They are populated by the `init` function.
// TODO: to prevent other users from changing these variables, we could probably just publish our own package like https://pkg.go.dev/github.com/cosmos/cosmos-sdk/version
var (
AccountAddressPrefix = "pfeath"
AccountPubKeyPrefix = "pfeathpub"
ValidatorAddressPrefix = "pfeathvaloper"
ValidatorPubKeyPrefix = "pfeathvaloperpub"
ConsensusNodeAddressPrefix = "pfeathvalcons"
ConsensusNodePubKeyPrefix = "pfeathvalconspub"
BondDenom = "stake"
AppName = "feather-core"
AccountAddressPrefix string
Name string
BondDenom string
)

// TODO: What is this?
Expand Down Expand Up @@ -257,12 +253,21 @@ var (
)

func init() {
userHomeDir, err := os.UserHomeDir()
// Load and use config from config.json
config, err := cfg.Load()
if err != nil {
panic(err)
}
Name = config.AppName
BondDenom = config.BondDenom
AccountAddressPrefix = config.AddressPrefix

DefaultNodeHome = filepath.Join(userHomeDir, "."+AppName)
// Set default home dir for app at ~/.<Name>
userHomeDir, err := os.UserHomeDir()
if err != nil {
panic(err)
}
DefaultNodeHome = filepath.Join(userHomeDir, "."+Name)
}

// App extends an ABCI application, but with most of its parameters exported.
Expand Down Expand Up @@ -342,7 +347,7 @@ func New(
// Init App
app := &App{
BaseApp: baseapp.NewBaseApp(
AppName,
Name,
logger,
db,
encodingConfig.TxConfig.TxDecoder(),
Expand Down Expand Up @@ -1098,7 +1103,7 @@ func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig

// register app's OpenAPI routes.
apiSvr.Router.Handle("/static/openapi.yml", http.FileServer(http.FS(docs.Docs)))
apiSvr.Router.HandleFunc("/", openapiconsole.Handler(AppName, "/static/openapi.yml"))
apiSvr.Router.HandleFunc("/", openapiconsole.Handler(Name, "/static/openapi.yml"))
}

// RegisterTxService implements the Application.RegisterTxService method.
Expand Down
Loading

0 comments on commit 906b2d5

Please sign in to comment.