Klyra Chain Protocol
Sovereign Blockchain built using Cosmos SDK & CometBFT for Klyra Protocol.
Get started
Installation
- Install Go
1.21
here.
- Install Docker Desktop here
- Run
make install
to install project dependencies.
Helpful Development Commands
make test
runs unit tests.
make lint
lints source code (make lint-fix
to also fix).
make build
builds source.
make mock-gen
generates mocks for files listed in mocks/Makefile. More info about mocking here.
Running the chain locally
Requirements: Ensure you are running docker-compose version 1.30.x
or newer, and Docker engine version 20.10.x
or newer.
You can quickly test your changes to Klyra Chain with just a few commands:
-
Make any change to the Klyra Chain code that you want to test
-
Once ready to test, run make localnet-start
(or make localnet-startd
to run the network headlessly)
- This first compiles all your changes to docker image called
klyraprotocol-base
(~90 seconds)
- You will then be running a local network with your changes!
- Note, these commands will reset the chain to genesis
-
To remove all block history and start from scratch, re-run make localnet-start
or make localnet-startd
.
-
To stop the chain but keep the state, run make localnet-stop
. To restart the protocol with the previous state, run make localnet-continue
.
Deployment to AWS testnets
Merges to the main
branch automatically trigger a new Docker container image to be built and pushed to ECR. After the image has been pushed to ECR, a Terraform Cloud run is currently necessary to deploy the new container to ECS.
The following commands can be used to locally build and push containers to ECR.
make aws-push-dev
locally build and push a container image to the "dev" environment.
make aws-push-dev2
locally build and push a container image to the "dev2" environment.
make aws-push-dev3
locally build and push a container image to the "dev3" environment.
make aws-push-dev4
locally build and push a container image to the "dev4" environment.
make aws-push-dev5
locally build and push a container image to the "dev5" environment.
make aws-push-staging
locally build and push a container image to the "staging" environment.
Linting
We use yamllint
for linting YAML files. Instructions for using specific
yamllint
actions are linked below:
We currently lint the following YAML files in the Lint
CI job:
.golangci.yml
.
.github/workflows/*.yml
.
- Note this includes all files that end in the
yml
file extension in the .github/workflows
directory.
buf.work.yaml
.
Protos
Protos can be found in ../proto/
here.
Genesis
You can find the local chain's genesis data in testing/genesis.sh
. This dictates the starting app state of your chain when running make localnet-start
. We currently start the chain with BTC and ETH perpetuals and prices but could easily add another perpetual and market like so:
...
dasel put string -f "$GENESIS" '.app_state.perpetuals.perpetuals.[2].ticker' 'LINK-USD'
dasel put int -f "$GENESIS" '.app_state.perpetuals.perpetuals.[2].market_id' '1'
dasel put int -f "$GENESIS" '.app_state.perpetuals.perpetuals.[2].atomic_resolution' -v '-9'
dasel put int -f "$GENESIS" '.app_state.perpetuals.perpetuals.[2].default_funding_ppm' '0'
dasel put int -f "$GENESIS" '.app_state.perpetuals.perpetuals.[2].initial_margin_ppm' '50000' # 5 %
dasel put int -f "$GENESIS" '.app_state.perpetuals.perpetuals.[2].maintenance_fraction_ppm' '600000' # 3 % (60% of IM)
...
dasel put string -f "$GENESIS" '.app_state.prices.markets.[2].pair' 'LINK-USD'
dasel put int -f "$GENESIS" '.app_state.prices.markets.[2].exponent' -v '-6'
dasel put int -f "$GENESIS" '.app_state.prices.markets.[2].min_exchanges' '1'
dasel put int -f "$GENESIS" '.app_state.prices.markets.[2].min_price_change_ppm' '50'
dasel put int -f "$GENESIS" '.app_state.prices.markets.[2].price' '3000000000' # $3,000 = 1 ETH.
dasel put int -f "$GENESIS" '.app_state.prices.markets.[2].exchanges.[0]' '0'
Another module that can be modified similarly is the subaccounts. We can add another subaccount by updating the TEST_ACCOUNTS
array in ./testing/local.sh
.
Debugging Tips
Setting up keychain
To run the below commands, you'll want to import the private keys of the test accounts specified in testnet-local/local.sh. Run the following commands and input the corresponding 12-word string from MNEMONICS
. The resulting address should match those in TEST_ACCOUNTS
.
./build/klyraprotocold keys add alice --recover
./build/klyraprotocold keys add bob --recover
Send a test transaction locally
It's occasionally helpful to send a transaction to the local chain to observe Cosmos behavior through the API such as events. Until clob
v0.1
is complete, you can use the default Cosmos bank
module to transfer assets between two accounts defined at genesis in the genesis.sh
file.
./build/klyraprotocold tx bank send klyra199tqg4wdlnu4qjlxchpd7seg454937hju8xa57 klyra10fx7sy6ywd5senxae9dwytf8jxek3t2g8gx9ym 100usdc
Placing a test order locally
It's occasionally helpful to send a transaction to the local chain to test order placement and matching. Run the following two commands in succession in order to match an order between two accounts.
./build/klyraprotocold tx clob place-order klyra199tqg4wdlnu4qjlxchpd7seg454937hju8xa57 0 0 0 1 10 10000 20 --from alice --chain-id localklyraprotocol
./build/klyraprotocold tx clob place-order klyra10fx7sy6ywd5senxae9dwytf8jxek3t2g8gx9ym 0 0 0 2 10 10000 20 --from bob --chain-id localklyraprotocol
Run the following command to cancel an order.
./build/klyraprotocold tx clob cancel-order klyra199tqg4wdlnu4qjlxchpd7seg454937hju8xa57 10 0 20 --from alice
Querying the chain locally
While running the development server via make localnet-start
, you can make queries locally using the Tendermint API. All endpoints listed here are supported. For example to get the block at height 2: curl -X GET "localhost:26657/block?height=2"
.
Updating local flags
When debugging or inspecting behavior of the chain locally, you may wish modify the flags passed to klyraprotocold
. You can achieve this by modifying your docker-compose.yml
file locally in the entrypoint
section to change these passed in flags.
Enabled more verbose logging locally
Refer to the section above and change the log_level
to trace
. Note that trace
can be pretty noisy as it logs every block proposal, message, and committed block to stdout.
Debugging behavior in Cosmos SDK
It's occasionally useful to be able to output logs or modify behavior in cosmos-sdk
itself. To do this, check out cosmos-sdk locally at the branch which represents the version specified in the go.mod
file in this repository.
git clone git@github.com:cosmos/cosmos-sdk.git
git checkout v0.47.0-alpha2
After you've cloned the repo, you can modify the go.mod
file in v4-chain
locally to include a replace directive which locally points cosmos-sdk
to your local version of cosmos-sdk
. Example:
replace (
+ github.com/cosmos/cosmos-sdk v0.47.0-alpha2 => /Users/bryce/projects/cosmos-sdk
github.com/keybase/go-keychain => github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4
google.golang.org/grpc => google.golang.org/grpc v1.50.1
)
Now running make localnet-start
will include any changes you've made to your cosmos-sdk
repository locally.
Slowing down blocks
It may be useful for debugging purposes to change the speed at which blocks are committed. This can be useful for more easily sending multiple transactions within the same block, or just for reducing the noise of the --verbose
output (which includes output every time a new block is committed).
For example, for a block time of 1 minute
, add the following lines to your local.sh
file locally in this repository:
# How long we wait for a proposal block before prevoting nil
dasel put string -f "$CONFIG_FOLDER"/config.toml '.consensus.timeout_propose' '60s'
# How long we wait after committing a block, before starting on the new
# height (this gives us a chance to receive some more precommits, even
# though we already have +2/3).
dasel put string -f "$CONFIG_FOLDER"/config.toml '.consensus.timeout_commit' '60s'
CometBFT fork
Our current implementation contains a light fork of CometBFT. The fork can be found here. Instructions to update the fork are included there.
CosmosSDK fork
Our current implementation contains a light fork of CosmosSDK. The fork can be found here. Instructions to update the fork are included there.
Daemons
Daemons are background processes that run in go-routines to do asyncronous work. Daemons can be configured with their respective flags, e.g. price-daemon-enabled
or price-daemon-delay-loop-ms
.
TODO(CORE-512): update daemon flags
Liquidation Daemon
TODO(CORE-512): add details
Pricefeed Daemon
The Pricefeed Daemon is responsible for ingesting prices from 3rd party exchanges like Binance and sending these prices to the application where they are then used by the Prices module. The Pricefeed daemon is started by default when the application starts.
TODO(CORE-469): update doc with new ways to override the params
Learn more