diff --git a/.circleci/config.yml b/.circleci/config.yml index 07497767c..6d113f9d5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -70,7 +70,7 @@ jobs: - run: docker swarm init - <<: *restore_go_cache - <<: *restore_go_path - - run: make e2e + - run: make e2e version=`echo $CIRCLE_SHA1 | cut -c1-7` - <<: *save_go_path - <<: *save_go_cache diff --git a/.dockerignore b/.dockerignore index 8de3f1617..3110d40ff 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,7 +11,6 @@ CONTRIBUTING.md schema1.svg .github -/scripts /examples # test & debug files diff --git a/Dockerfile.cli.dev b/Dockerfile.cli.dev new file mode 100644 index 000000000..5be25223c --- /dev/null +++ b/Dockerfile.cli.dev @@ -0,0 +1,8 @@ +ARG from +FROM $from + +COPY ./dev-chain/cli /root/.mesg-cli +COPY ./dev-chain/validator /root/.mesg-node +COPY ./scripts/dev-cli.sh . + +CMD ["bash", "dev-cli.sh"] diff --git a/Makefile b/Makefile index bf13bef47..eee6cc5b6 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all build build-cmd-cosmos changelog check-version clean clean-build clean-docker dep dev dev-mon dev-start dev-stop docker-build docker-dev docker-publish docker-publish-dev docker-tools genesis lint protobuf test publish-cmds build-docker-cli +.PHONY: all build build-cmd-cosmos changelog check-version clean clean-build clean-docker dep dev dev-mon dev-start dev-stop docker-build docker-dev docker-publish docker-publish-dev docker-tools genesis lint protobuf test publish-cmds build-docker-cli build-docker-cli-dev MAJOR_VERSION := $(shell echo $(version) | cut -d . -f 1) MINOR_VERSION := $(shell echo $(version) | cut -d . -f 1-2) @@ -64,7 +64,10 @@ build-cmd: dep build-docker-cli: check-version docker build -t mesg/engine:cli -f ./Dockerfile.cli --build-arg version=$(version) . -e2e: docker-dev +build-docker-cli-dev: build-docker-cli + docker build -t mesg/engine:cli-dev -f ./Dockerfile.cli.dev --build-arg from=mesg/engine:cli . + +e2e: build-docker-cli-dev ./scripts/run-e2e.sh test: dep diff --git a/dev-chain/README.md b/dev-chain/README.md new file mode 100644 index 000000000..1d636b10a --- /dev/null +++ b/dev-chain/README.md @@ -0,0 +1,30 @@ +# Dev chain + +For local use only. + +## Genesis file + +See file `dev-genesis.json` + +## Accounts + +### Validator + +Address: `mesg10cjcxje0jjdxzdq5hpqa4dc4znhuxsax2zh7mp` +Pubkey: `mesgpub1addwnpepq0gwhzul5qcycxxs6r7jdzdn5q29mj2a8gmngfrcfa6l8qs2dar4s2jqycv` +Mnemonic: `fruit lock run bike eyebrow unique embrace cost parade welcome more frown oxygen crane club donate grid harsh marriage host skirt sign warfare cup` +Coins: 100000000stake (but used in gentx) + +### CLI + +Address: `mesg1s6mqusxaq93d70jeekqehg7aepwt7zs306ctq7` +Pubkey: `mesgpub1addwnpepqvdrcdvg3x4tf0y5aapn47njxapdu4l0jgsjzcm2klp9a7eztva66eqnadt` +Mnemonic: `spike raccoon obscure program raw large unaware dragon hamster round artist case fall wage sample velvet robust legend identify innocent film coral picture organ` +Coins: 1000000000000000000000000atto and 1000000000stake + +### Orchestrator + +Address: `mesg1t9h20sn3lk2jdnak5eea4lkqxkpwyfaadtqk4t` +Pubkey: `mesgpub1addwnpepqde3ek5edcpxded9w2rw05jm4z3my57f7dey5pwz8hs0uzw0c3xusqmd53d` +Mnemonic: `neutral false together tattoo matrix stamp poem mouse chair chair grain pledge mandate layer shiver embark struggle vicious antenna total faith genre valley mandate` +Coins: 1000000000000000000000000atto diff --git a/dev-chain/cli/config/config.toml b/dev-chain/cli/config/config.toml new file mode 100644 index 000000000..9aeb0e993 --- /dev/null +++ b/dev-chain/cli/config/config.toml @@ -0,0 +1,6 @@ +trust-node = "true" +chain-id = "mesg-dev-chain" + +# orchestrtor +authorized-pubkeys = "mesgpub1addwnpepqvdrcdvg3x4tf0y5aapn47njxapdu4l0jgsjzcm2klp9a7eztva66eqnadt" +mnemonic = "neutral false together tattoo matrix stamp poem mouse chair chair grain pledge mandate layer shiver embark struggle vicious antenna total faith genre valley mandate" diff --git a/dev-chain/validator/config/app.toml b/dev-chain/validator/config/app.toml new file mode 100644 index 000000000..188b3caf1 --- /dev/null +++ b/dev-chain/validator/config/app.toml @@ -0,0 +1,4 @@ +# The minimum gas prices a validator is willing to accept for processing a +# transaction. A transaction's fees must meet the minimum of any denomination +# specified in this config (e.g. 0.25token1;0.0001token2). +minimum-gas-prices = "1.0atto" diff --git a/dev-chain/validator/config/config.toml b/dev-chain/validator/config/config.toml new file mode 100644 index 000000000..7673e561d --- /dev/null +++ b/dev-chain/validator/config/config.toml @@ -0,0 +1,12 @@ +moniker = "developer" +[rpc] +laddr = "tcp://0.0.0.0:26657" +max_subscriptions_per_client = 100 +[consensus] +timeout_commit = "1s" +[p2p] +addr_book_strict = false +[instrumentation] +prometheus = true +[tx_index] +index_all_keys = true diff --git a/dev-chain/validator/config/genesis.json b/dev-chain/validator/config/genesis.json new file mode 100644 index 000000000..b7dee0ba9 --- /dev/null +++ b/dev-chain/validator/config/genesis.json @@ -0,0 +1,196 @@ +{ + "genesis_time": "2020-05-02T09:36:48.27599Z", + "chain_id": "mesg-dev-chain", + "consensus_params": { + "block": { + "max_bytes": "22020096", + "max_gas": "-1", + "time_iota_ms": "1000" + }, + "evidence": { + "max_age_num_blocks": "100000", + "max_age_duration": "172800000000000" + }, + "validator": { + "pub_key_types": [ + "ed25519" + ] + } + }, + "app_hash": "", + "app_state": { + "auth": { + "params": { + "max_memo_characters": "256", + "tx_sig_limit": "7", + "tx_size_cost_per_byte": "10", + "sig_verify_cost_ed25519": "590", + "sig_verify_cost_secp256k1": "1000" + }, + "accounts": [ + { + "type": "cosmos-sdk/Account", + "value": { + "address": "mesg1t9h20sn3lk2jdnak5eea4lkqxkpwyfaadtqk4t", + "coins": [ + { + "denom": "atto", + "amount": "1000000000000000000000000" + } + ], + "public_key": "", + "account_number": 0, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "mesg10cjcxje0jjdxzdq5hpqa4dc4znhuxsax2zh7mp", + "coins": [ + { + "denom": "stake", + "amount": "100000000" + } + ], + "public_key": "", + "account_number": 0, + "sequence": 0 + } + }, + { + "type": "cosmos-sdk/Account", + "value": { + "address": "mesg1s6mqusxaq93d70jeekqehg7aepwt7zs306ctq7", + "coins": [ + { + "denom": "atto", + "amount": "1000000000000000000000000" + }, + { + "denom": "stake", + "amount": "1000000000" + } + ], + "public_key": "", + "account_number": 0, + "sequence": 0 + } + } + ] + }, + "params": null, + "service": {}, + "slashing": { + "params": { + "signed_blocks_window": "100", + "min_signed_per_window": "0.500000000000000000", + "downtime_jail_duration": "600000000000", + "slash_fraction_double_sign": "0.050000000000000000", + "slash_fraction_downtime": "0.010000000000000000" + }, + "signing_infos": {}, + "missed_blocks": {} + }, + "instance": {}, + "runner": {}, + "distribution": { + "params": { + "community_tax": "0.020000000000000000", + "base_proposer_reward": "0.010000000000000000", + "bonus_proposer_reward": "0.040000000000000000", + "withdraw_addr_enabled": true + }, + "fee_pool": { + "community_pool": [] + }, + "delegator_withdraw_infos": [], + "previous_proposer": "", + "outstanding_rewards": [], + "validator_accumulated_commissions": [], + "validator_historical_rewards": [], + "validator_current_rewards": [], + "delegator_starting_infos": [], + "validator_slash_events": [] + }, + "supply": { + "supply": [] + }, + "staking": { + "params": { + "unbonding_time": "1814400000000000", + "max_validators": 100, + "max_entries": 7, + "historical_entries": 0, + "bond_denom": "stake" + }, + "last_total_power": "0", + "last_validator_powers": null, + "validators": null, + "delegations": null, + "unbonding_delegations": null, + "redelegations": null, + "exported": false + }, + "bank": { + "send_enabled": true + }, + "process": {}, + "ownership": {}, + "genutil": { + "gentxs": [ + { + "type": "cosmos-sdk/StdTx", + "value": { + "msg": [ + { + "type": "cosmos-sdk/MsgCreateValidator", + "value": { + "description": { + "moniker": "developer", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "commission": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "min_self_delegation": "1", + "delegator_address": "mesg10cjcxje0jjdxzdq5hpqa4dc4znhuxsax2zh7mp", + "validator_address": "mesgvaloper10cjcxje0jjdxzdq5hpqa4dc4znhuxsaxkrzt5d", + "pubkey": "mesgvalconspub1zcjduepqsmu3d8sjzfgc9hv994484kh6g7w6k7hwa6pz6ytx8xl02u0vx7uq3c5hd7", + "value": { + "denom": "stake", + "amount": "100000000" + } + } + } + ], + "fee": { + "amount": [], + "gas": "200000" + }, + "signatures": [ + { + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "A9Dri5+gMEwY0ND9JomzoBRdyV06NzQkeE9184IKb0dY" + }, + "signature": "9BgADIZvkzMA5qPU05MBiF4jpnmFXOvLd2/0U9t4MSsRThtvUYNkKpdRed/I8RVzjC3DTsIpbfo7PA8iWb1Hbg==" + } + ], + "memo": "a4ed9cf59270fd2e867241cd1134bba019e8452f@192.168.1.110:26656" + } + } + ] + }, + "execution": { + "params": { + "minPrice": "10000atto" + } + } + } +} \ No newline at end of file diff --git a/dev-chain/validator/config/node_key.json b/dev-chain/validator/config/node_key.json new file mode 100644 index 000000000..33417858c --- /dev/null +++ b/dev-chain/validator/config/node_key.json @@ -0,0 +1 @@ +{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"WnB/ngV9sCHm6WruylEat+XRbmhnJ1dgTdAPIIHWiKVeZeftLREe8aUjz7+2QKdKQkJwovw3b0rFa2Z+Z2zLXw=="}} \ No newline at end of file diff --git a/dev-chain/validator/config/priv_validator_key.json b/dev-chain/validator/config/priv_validator_key.json new file mode 100644 index 000000000..d17eae7d0 --- /dev/null +++ b/dev-chain/validator/config/priv_validator_key.json @@ -0,0 +1,11 @@ +{ + "address": "AE7AAC113558ABD2B3D24EDC3774FBE7027F1F35", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "hvkWnhISUYLdhS1qetr6R52reu7ugi0RZjm+9XHsN7g=" + }, + "priv_key": { + "type": "tendermint/PrivKeyEd25519", + "value": "O8EZc8rbvs5H4+fdFX3uIzxULm4c6/Yxl5+9yIqkc36G+RaeEhJRgt2FLWp62vpHnat67u6CLRFmOb71cew3uA==" + } +} \ No newline at end of file diff --git a/dev-chain/validator/data/priv_validator_state.json b/dev-chain/validator/data/priv_validator_state.json new file mode 100644 index 000000000..ca3ad2f74 --- /dev/null +++ b/dev-chain/validator/data/priv_validator_state.json @@ -0,0 +1,5 @@ +{ + "height": "0", + "round": "0", + "step": 0 +} \ No newline at end of file diff --git a/e2e/api_test.go b/e2e/api_test.go index 3fa52dbde..57905c7a8 100644 --- a/e2e/api_test.go +++ b/e2e/api_test.go @@ -11,7 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/bank" "github.com/mesg-foundation/engine/app" "github.com/mesg-foundation/engine/config" "github.com/mesg-foundation/engine/container" @@ -41,14 +40,14 @@ var ( lcd *cosmos.LCD lcdEngine *cosmos.LCD cliAddress sdk.AccAddress - cliInitialBalance, _ = sdk.ParseCoins("100000000000000000000000000atto") ) const ( lcdEndpoint = "http://127.0.0.1:1317/" pollingInterval = 500 * time.Millisecond // half a block pollingTimeout = 10 * time.Second // 10 blocks - cliAccountMnemonic = "large fork soccer lab answer enlist robust vacant narrow please inmate primary father must add hub shy couch rail video tool marine pill give" + engineMnemonic = "neutral false together tattoo matrix stamp poem mouse chair chair grain pledge mandate layer shiver embark struggle vicious antenna total faith genre valley mandate" + cliAccountMnemonic = "spike raccoon obscure program raw large unaware dragon hamster round artist case fall wage sample velvet robust legend identify innocent film coral picture organ" cliAccountName = "cli" cliAccountPassword = "pass" ) @@ -77,7 +76,7 @@ func TestAPI(t *testing.T) { kb, err = cosmos.NewKeybase(filepath.Join(cfg.Path, cfg.Cosmos.RelativePath)) require.NoError(t, err) // init engine account - engineAcc, err := kb.CreateAccount(cfg.Account.Name, cfg.Account.Mnemonic, "", cfg.Account.Password, keys.CreateHDPath(cfg.Account.Number, cfg.Account.Index).String(), cosmos.DefaultAlgo) + engineAcc, err := kb.CreateAccount(cfg.Account.Name, engineMnemonic, "", cfg.Account.Password, keys.CreateHDPath(cfg.Account.Number, cfg.Account.Index).String(), cosmos.DefaultAlgo) require.NoError(t, err) engineAddress = engineAcc.GetAddress() @@ -89,8 +88,6 @@ func TestAPI(t *testing.T) { // init LCD with engine account and make a transfer to cli account lcdEngine, err = cosmos.NewLCD(lcdEndpoint, cdc, kb, cfg.DevGenesis.ChainID, cfg.Account.Name, cfg.Account.Password, cfg.Cosmos.MinGasPrices) require.NoError(t, err) - _, err = lcdEngine.BroadcastMsg(bank.NewMsgSend(engineAddress, cliAddress, cliInitialBalance)) - require.NoError(t, err) // init container cont, err = container.New(cfg.Name, cfg.Server.Address, cfg.Name) diff --git a/e2e/testdata/e2e.config.yml b/e2e/testdata/e2e.config.yml deleted file mode 100644 index 105e537c7..000000000 --- a/e2e/testdata/e2e.config.yml +++ /dev/null @@ -1,8 +0,0 @@ -authorized_pubkeys: - - mesgpub1addwnpepqg0ujk8vcwq86z8466rznfvfz5rk992wsy0qtczfedgsy3x90mrzkcd5srf -account: - mnemonic: glimpse upon body vast economy give taxi yellow rabbit come click ranch chronic hammer sport near rotate charge lumber chicken cloud base thing forum -tendermint: - config: - consensus: - timeoutcommit: 1s diff --git a/scripts/dev-cli.sh b/scripts/dev-cli.sh new file mode 100755 index 000000000..f4853e4db --- /dev/null +++ b/scripts/dev-cli.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# turn on bash's job control +set -m + +# start daemon +mesg-daemon start & +daemon=$! + +# wait 5 sec for the daemon to start rpc server +sleep 5 & +wait $! + +# start lcd +mesg-cli rest-server --laddr tcp://0.0.0.0:1317 & +lcd=$! + +# start orchestrator +mesg-cli orchestrator start & +orchestrator=$! + +# this variable is used to control the monitoring of the child process +monitoring=true + +# function that stop child processes +function stop { + monitoring=false + echo "stopping all child processes" + kill $daemon $lcd $orchestrator + wait $daemon $lcd $orchestrator +} + +# trap both sigint (ctrl+c) and sigterm (OS ask process to be stopped) +trap stop SIGINT +trap stop SIGTERM + +# start the monitoring loop +while $monitoring +do + # check if all sub processes are running correctly + if [[ -n "$(ps -p $daemon -o pid=)" ]] && [[ -n "$(ps -p $lcd -o pid=)" ]] && [[ -n "$(ps -p $orchestrator -o pid=)" ]]; then + sleep 2 & + wait $! + else + # if one child process is not running, stopping all of them and exit with error code 1 + echo "one child process is not running" + stop + exit 1 + fi +done diff --git a/scripts/run-e2e.sh b/scripts/run-e2e.sh index 4b58b3c99..7fbb37707 100755 --- a/scripts/run-e2e.sh +++ b/scripts/run-e2e.sh @@ -2,23 +2,39 @@ set -e -export MESG_PATH="$(pwd)"/e2e.test/mesg - -# first run non existing test to detect compilation error quickly +echo "run non existing test to detect compilation error quickly" go test -mod=readonly -v -count=1 ./e2e/... -run=__NONE__ function onexit { - set +e - ./scripts/dev.sh stop - rm -rf "${MESG_PATH}" + docker service rm engine + docker wait $(docker ps -f label=com.docker.swarm.service.name=engine -q) 2> /dev/null + + docker network remove engine } trap onexit EXIT -rm -rf "${MESG_PATH}" -mkdir -p "${MESG_PATH}" -cp "$(pwd)"/e2e/testdata/e2e.config.yml "${MESG_PATH}"/config.yml - -./scripts/dev.sh -q - +if [[ -z $(docker network list -f name="engine" -q) ]]; then + docker network create --driver overlay engine +fi +docker service create \ + --name engine \ + -p 1317:1317 \ + -p 50052:50052 \ + -p 26657:26657 \ + --network engine \ + --label com.docker.stack.namespace=engine \ + mesg/engine:cli-dev + +echo "waiting to give some time to the container to start and run" +while true; do + printf '.' + block=$(curl --silent http://localhost:1317/node_info | jq .node_info.protocol_version.block) + if [[ -n $block ]]; then + break + fi + sleep 1 +done + +echo "starting tests" go test -failfast -mod=readonly -v -count=1 ./e2e/...