diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0c46a4b..611bf4e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,14 +72,10 @@ jobs: protoc --version - name: Install wasm-opt run: cargo install wasm-opt --locked + - name: Install cosmwasm-check + run: cargo install cosmwasm-check --locked - name: WASM release build - run: RUSTFLAGS="-C link-arg=-s" cargo wasm --locked - - name: Optimize WASM artifacts - run: | - mkdir artifacts - for f in target/wasm32-unknown-unknown/release/*.wasm; do - wasm-opt -Os "$f" -o "artifacts/$(basename "$f")" - done + run: make build-opt - name: Generate checksums run: | cd artifacts @@ -108,12 +104,48 @@ jobs: sudo apt-get install -y protobuf-compiler protoc --version - name: Install cargo-tarpaulin - run: cargo +1.82.0 install cargo-tarpaulin + run: cargo +1.90.0 install cargo-tarpaulin - name: Run coverage - run: cargo +1.82.0 tarpaulin --workspace --all-features --all-targets --locked --out Xml --output-dir coverage + run: cargo +1.90.0 tarpaulin --workspace --all-features --all-targets --locked --out Xml --output-dir coverage - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} files: coverage/cobertura.xml fail_ci_if_error: true + + e2e: + name: E2E + runs-on: ubuntu-latest + needs: fmt_lint + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Set up Docker Compose + uses: docker/setup-buildx-action@v2 + - name: Install test deps + run: | + sudo apt-get update + sudo apt-get install -y bats jq + bats --version + jq --version + - name: Install toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ env.RUST_VERSION }} + targets: wasm32-unknown-unknown + - name: Install protoc + run: | + sudo apt-get update + sudo apt-get install -y protobuf-compiler + protoc --version + - name: Install wasm-opt + run: cargo install wasm-opt --locked + - name: Install cosmwasm-check + run: cargo install cosmwasm-check --locked + - name: E2E test + run: bats e2e/tests/converter.bats + - name: Cleanup + if: always() + run: docker compose -f e2e/docker-compose.yml down -v diff --git a/.gitignore b/.gitignore index c403c34..b0d8521 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target .idea/ +artifacts/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..41ce0c5 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "e2e/test_helper/bats-support"] + path = e2e/test_helper/bats-support + url = https://github.com/bats-core/bats-support +[submodule "e2e/test_helper/bats-assert"] + path = e2e/test_helper/bats-assert + url = https://github.com/bats-core/bats-assert diff --git a/Cargo.toml b/Cargo.toml index f8c2669..a538776 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ resolver = "2" [workspace.package] version = "0.1.0" +rust-version = "1.86.0" [workspace.dependencies] bech32 = "0.11" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..07ff012 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +MAKEFLAGS += --no-print-directory + +e2e-chain-up: + @echo "--> Starting e2e test blockchain environment" + @docker compose -f e2e/docker-compose.yml up -d --wait + +e2e-chain-down: + @echo "--> Stopping e2e test blockchain environment" + @docker compose -f e2e/docker-compose.yml down -v + +.PHONY: e2e-chain-up e2e-chain-down + +#### Build #### + +build: + @echo "--> Building contracts" + @cargo wasm + +build-opt: + @echo "--> Checking for protoc installation" + @$(MAKE) check-protoc + @echo "--> Checking for wasm-opt installation" + @$(MAKE) check-wasm-opt + @echo "--> Checking for cosmwasm-check installation" + @$(MAKE) check-cosmwasm-check + @echo "--> Building optimized contracts" + @RUSTFLAGS="-C link-arg=-s" cargo wasm --locked + @echo "--> Optimizing wasm binaries" + @mkdir -p ./artifacts/ + @for f in target/wasm32-unknown-unknown/release/*.wasm; do wasm-opt -Os "$$f" -o "artifacts/$$(basename "$$f")"; done + @echo "--> Optimized wasm binaries are in the ./artifacts/ directory" + @echo "--> Running cosmwasm-check on optimized binaries" + @for f in artifacts/*.wasm; do cosmwasm-check "$$f"; done + +clean: + @echo "--> Cleaning build artifacts" + @cargo clean + +check-protoc: + @command -v protoc >/dev/null 2>&1 || { echo "protoc not found; install with: sudo apt install protobuf-compiler (or your distro's package)"; exit 1; } + +check-wasm-opt: + @command -v wasm-opt >/dev/null 2>&1 || { echo "wasm-opt not found; install with: sudo apt install binaryen (or your distro's package)"; exit 1; } + +check-cosmwasm-check: + @command -v cosmwasm-check >/dev/null 2>&1 || { echo "cosmwasm-check not found; install with: cargo install cosmwasm-check"; exit 1; } + +.PHONY: build clean build-opt check-protoc check-wasm-opt check-cosmwasm-check \ No newline at end of file diff --git a/contracts/converter/src/msg.rs b/contracts/converter/src/msg.rs index 3e626f9..b7bed9f 100644 --- a/contracts/converter/src/msg.rs +++ b/contracts/converter/src/msg.rs @@ -25,7 +25,9 @@ pub enum QueryMsg { } #[cw_serde] -pub enum MigrateMsg {} +pub enum MigrateMsg { + Migrate {}, +} // TODO: Write a macro to generate this struct from the Config struct #[cw_serde] diff --git a/e2e/.env b/e2e/.env new file mode 100644 index 0000000..56a581d --- /dev/null +++ b/e2e/.env @@ -0,0 +1,35 @@ +KEY="user1" +KEY2="user2" +ADDR1="manifest1hj5fveer5cjtn4wd6wstzugjfdxzl0xp8ws9ct" +ADDR2="manifest1efd63aw40lxf3n4mhf7dzhjkr453axurm6rp3z" +VESTING_ADDR="manifest1yyuzq9665yjmmhnmfn7zsajnyz9lcdelggf6ke" +CHAIN_ID="test-1" +MONIKER="zebradonkey" +KEYRING="test" +HOME_DIR="/persistent/.manifest" +BINARY="/usr/bin/manifestd" +MNEMO1="decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry" +MNEMO2="wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise" +BANK_ADDR=manifest1hj5fveer5cjtn4wd6wstzugjfdxzl0xp8ws9ct +GAS_STATION_ADDR=manifest1efd63aw40lxf3n4mhf7dzhjkr453axurm6rp3z +RPC="26657" +REST="1317" +PROFF="6060" +P2P="26656" +GRPC="9090" +GRPC_WEB="9091" +ROSETTA="8080" +TIMEOUT_COMMIT="3s" +VOTING_TIMEOUT="10s" +DENOM=umfx +BOND_DENOM=upoa +POA_ADMIN_ADDRESS="manifest1hj5fveer5cjtn4wd6wstzugjfdxzl0xp8ws9ct" +USER_GROUP_ADDRESS="manifest1dlszg2sst9r69my4f84l3mj66zxcf3umcgujys30t84srg95dgvsmxrlcr" +COMMON_MANIFESTD_ARGS="--gas-prices 0.0011${DENOM} --gas-adjustment 1.8 --gas auto --home ${HOME_DIR} --keyring-backend $KEYRING --chain-id $CHAIN_ID --yes --node http://manifest-ledger:$RPC" +GROUP_MEMBERS={"members":[{"address":"${ADDR1}","weight":"1","metadata":"user1"},{"address":"${ADDR2}","weight":"1","metadata":"user2"}]} +DECISION_POLICY={"@type":"/cosmos.group.v1.ThresholdDecisionPolicy","threshold":"1","windows":{"voting_period":"10s","min_execution_period":"0s"}} +TX_COUNT_DIR=/tx-count +TX_COUNT_FILE=tx-count.txt +TX_COUNT_PATH="${TX_COUNT_DIR}/${TX_COUNT_FILE}" +POSTGREST_HOST=postgrest +CONVERT_WASM_ADDRESS="manifest14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s4zfs7u" diff --git a/e2e/docker-compose.yml b/e2e/docker-compose.yml new file mode 100644 index 0000000..94c1169 --- /dev/null +++ b/e2e/docker-compose.yml @@ -0,0 +1,23 @@ +services: + manifest-ledger: + image: ghcr.io/manifest-network/manifest-ledger:1.0.11 + volumes: + - manifest-ledger-bin:/usr/bin + - manifest-ledger-data:/persistent + - ./scripts/init_manifest_ledger.sh:/usr/local/bin/init_manifest_ledger.sh:ro + - ../:/workspace:ro + ports: + - "9090:9090" + - "26657:26657" + entrypoint: ["/bin/bash", "-c"] + env_file: ./.env + command: /usr/local/bin/init_manifest_ledger.sh + healthcheck: + test: manifestd status | grep '"earliest_block_height":"1"' + interval: 10s + timeout: 5s + retries: 5 + +volumes: + manifest-ledger-bin: + manifest-ledger-data: diff --git a/e2e/scripts/init_manifest_ledger.sh b/e2e/scripts/init_manifest_ledger.sh new file mode 100755 index 0000000..6a8e9d7 --- /dev/null +++ b/e2e/scripts/init_manifest_ledger.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# This script initializes the manifest ledger genesis file and starts a ledger node + +set -e + +update_test_genesis () { + cat $HOME_DIR/config/genesis.json | jq "$1" > $HOME_DIR/config/tmp_genesis.json && mv $HOME_DIR/config/tmp_genesis.json $HOME_DIR/config/genesis.json +} + +echo "$MNEMO1" | $BINARY keys add "$KEY" --home="$HOME_DIR" --keyring-backend "$KEYRING" --recover +echo "$MNEMO2" | $BINARY keys add "$KEY2" --home="$HOME_DIR" --keyring-backend "$KEYRING" --recover +$BINARY init $MONIKER --home=$HOME_DIR --chain-id $CHAIN_ID +update_test_genesis '.consensus["params"]["block"]["max_gas"]="1000000000"' +update_test_genesis '.app_state["bank"]["denom_metadata"]=[{"base":"umfx","denom_units":[{"aliases":[],"denom":"umfx","exponent":0},{"aliases":[],"denom":"MFX","exponent":6}],"description":"MFX","display":"MFX","name":"MFX","symbol":"MFX","uri":"","uri_hash":""}]' +update_test_genesis '.app_state["gov"]["params"]["min_deposit"]=[{"denom":"'$DENOM'","amount":"1000000"}]' +update_test_genesis '.app_state["gov"]["params"]["voting_period"]="15s"' +update_test_genesis '.app_state["gov"]["params"]["expedited_voting_period"]="10s"' +update_test_genesis '.app_state["staking"]["params"]["bond_denom"]="'${BOND_DENOM}'"' +update_test_genesis '.app_state["staking"]["params"]["min_commission_rate"]="0.000000000000000000"' +update_test_genesis '.app_state["mint"]["params"]["mint_denom"]="'$DENOM'"' +update_test_genesis '.app_state["mint"]["params"]["blocks_per_year"]="6311520"' +update_test_genesis '.app_state["tokenfactory"]["params"]["denom_creation_fee"]=[]' +update_test_genesis '.app_state["tokenfactory"]["params"]["denom_creation_gas_consume"]=0' +update_test_genesis '.app_state["feegrant"]["allowances"]=[{"granter":"'${GAS_STATION_ADDR}'","grantee":"'${BANK_ADDR}'","allowance":{"@type":"/cosmos.feegrant.v1beta1.AllowedMsgAllowance","allowance":{"@type":"/cosmos.feegrant.v1beta1.BasicAllowance","spend_limit":[],"expiration":null},"allowed_messages":["/cosmos.bank.v1beta1.MsgSend"]}}]' +update_test_genesis '.app_state["group"]["group_seq"]="1"' +update_test_genesis '.app_state["group"]["groups"]=[{"id":"1","admin":"'${POA_ADMIN_ADDRESS}'","metadata":"AQ==","version":"2","total_weight":"2","created_at":"2024-05-16T15:10:54.372190727Z"}]' +update_test_genesis '.app_state["group"]["group_members"]=[{"group_id":"1","member":{"address":"'${ADDR1}'","weight":"1","metadata":"user1","added_at":"2024-05-16T15:10:54.372190727Z"}},{"group_id":"1","member":{"address":"'${ADDR2}'","weight":"1","metadata":"user2","added_at":"2024-05-16T15:10:54.372190727Z"}}]' +update_test_genesis '.app_state["group"]["group_policy_seq"]="1"' +update_test_genesis '.app_state["group"]["group_policies"]=[{"address":"'${POA_ADMIN_ADDRESS}'","group_id":"1","admin":"'${POA_ADMIN_ADDRESS}'","metadata":"AQ==","version":"2","decision_policy":{"@type":"/cosmos.group.v1.ThresholdDecisionPolicy","threshold":"1","windows":{"voting_period":"'${VOTING_TIMEOUT}'","min_execution_period":"0s"}},"created_at":"2024-05-16T15:10:54.372190727Z"}]' +update_test_genesis '.app_state["tokenfactory"]["factory_denoms"]=[{"denom":"factory/manifest1afk9zr2hn2jsac63h4hm60vl9z3e5u69gndzf7c99cqge3vzwjzsfmy9qj/upwr","authority_metadata":{"admin":"manifest1hj5fveer5cjtn4wd6wstzugjfdxzl0xp8ws9ct"}}]' +update_test_genesis '.app_state["bank"]["denom_metadata"] |= . + [{"description":"PWR","denom_units":[{"denom":"factory/manifest1afk9zr2hn2jsac63h4hm60vl9z3e5u69gndzf7c99cqge3vzwjzsfmy9qj/upwr","exponent":0,"aliases":["PWR"]},{"denom":"PWR","exponent":6,"aliases":["factory/manifest1afk9zr2hn2jsac63h4hm60vl9z3e5u69gndzf7c99cqge3vzwjzsfmy9qj/upwr"]}],"base":"factory/manifest1afk9zr2hn2jsac63h4hm60vl9z3e5u69gndzf7c99cqge3vzwjzsfmy9qj/upwr","display":"PWR","name":"POWER","symbol":"PWR","uri":"","uri_hash":""}]' +update_test_genesis '.app_state["wasm"]["params"]["code_upload_access"]["permission"]="Everybody"' +update_test_genesis '.app_state["wasm"]["params"]["instantiate_default_permission"]="Everybody"' +$BINARY genesis add-genesis-account $KEY 100000000000000000${BOND_DENOM},100000000000000000000000000000${DENOM} --keyring-backend $KEYRING --home=$HOME_DIR +$BINARY genesis add-genesis-account $KEY2 100000000000000000${DENOM} --keyring-backend $KEYRING --home=$HOME_DIR +$BINARY genesis gentx $KEY 1000000${BOND_DENOM} --keyring-backend $KEYRING --home=$HOME_DIR --chain-id $CHAIN_ID --commission-rate=0.0 --commission-max-rate=1.0 --commission-max-change-rate=0.1 +$BINARY genesis collect-gentxs --home=$HOME_DIR +$BINARY genesis validate-genesis --home=$HOME_DIR +sed -i 's/laddr = "tcp:\/\/127.0.0.1:26657"/laddr = "tcp:\/\/0.0.0.0:'$RPC'"/g' $HOME_DIR/config/config.toml +sed -i 's/cors_allowed_origins = \[\]/cors_allowed_origins = \["\*"\]/g' $HOME_DIR/config/config.toml +sed -i 's/address = "tcp:\/\/localhost:1317"/address = "tcp:\/\/0.0.0.0:'$REST'"/g' $HOME_DIR/config/app.toml +sed -i 's/enable = false/enable = true/g' $HOME_DIR/config/app.toml +sed -i 's/pprof_laddr = "localhost:6060"/pprof_laddr = "localhost:'$PROFF'"/g' $HOME_DIR/config/config.toml +sed -i 's/laddr = "tcp:\/\/0.0.0.0:26656"/laddr = "tcp:\/\/0.0.0.0:'$P2P'"/g' $HOME_DIR/config/config.toml +sed -i 's/address = "localhost:9090"/address = "0.0.0.0:'$GRPC'"/g' $HOME_DIR/config/app.toml +sed -i 's/address = "localhost:9091"/address = "0.0.0.0:'$GRPC_WEB'"/g' $HOME_DIR/config/app.toml +sed -i 's/address = ":8080"/address = "0.0.0.0:'$ROSETTA'"/g' $HOME_DIR/config/app.toml +sed -i 's/timeout_commit = "5s"/timeout_commit = "'$TIMEOUT_COMMIT'"/g' $HOME_DIR/config/config.toml +POA_ADMIN_ADDRESS=${POA_ADMIN_ADDRESS} $BINARY start --home=${HOME_DIR} --pruning=nothing --minimum-gas-prices=0.0011${DENOM} --rpc.laddr="tcp://0.0.0.0:$RPC" diff --git a/e2e/test_helper/bats-assert b/e2e/test_helper/bats-assert new file mode 160000 index 0000000..f1e9280 --- /dev/null +++ b/e2e/test_helper/bats-assert @@ -0,0 +1 @@ +Subproject commit f1e9280eaae8f86cbe278a687e6ba755bc802c1a diff --git a/e2e/test_helper/bats-support b/e2e/test_helper/bats-support new file mode 160000 index 0000000..004e707 --- /dev/null +++ b/e2e/test_helper/bats-support @@ -0,0 +1 @@ +Subproject commit 004e707638eedd62e0481e8cdc9223ad471f12ee diff --git a/e2e/test_helper/common.sh b/e2e/test_helper/common.sh new file mode 100644 index 0000000..2f90b0f --- /dev/null +++ b/e2e/test_helper/common.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash + +run_tx() { + local desc=$1 + shift + echo "# --> $desc" >&3 + run docker exec "$CONTAINER_NAME" manifestd tx "$@" \ + --home "/persistent/.manifest" \ + --keyring-backend "test" \ + --gas auto \ + --gas-adjustment 1.8 \ + --gas-prices "$GAS_PRICES" \ + --chain-id "$CHAIN_ID" \ + --node "$RPC" \ + --yes \ + --output json + + assert_success + local json_output=$(echo "$output" | tail -n +3) + TX_HASH=$(echo "$json_output" | jq -r '.txhash') + ERR_CODE=$(echo "$json_output" | jq -r '.code') + assert [ -n "$TX_HASH" ] + assert [ "$ERR_CODE" -eq 0 ] + echo "# --> Transaction submitted with hash: $TX_HASH" >&3 + sleep 3 + + run docker exec "$CONTAINER_NAME" manifestd query tx "$TX_HASH" \ + --node "$RPC" \ + --output json + assert_success + ERR_CODE=$(echo "$output" | tail -n +2 | jq -r '.code') + if [ "$ERR_CODE" != "0" ]; then + echo "# ⚠️ Tx returned error code $ERR_CODE" >&3 + echo "$output" >&3 + fi +} + +query_json() { + local desc=$1 + shift + echo "# --> $desc" >&3 + run docker exec "$CONTAINER_NAME" manifestd query "$@" \ + --node "$RPC" --output json + assert_success + echo "$output" | tail -n +2 +} + +store_contract() { + run_tx "Storing contract on-chain" wasm store "/workspace/$WASM_FILE" --from "$USER_ADDR" + CODE_ID=$(docker exec "$CONTAINER_NAME" manifestd query tx "$TX_HASH" --node "$RPC" --output json | \ + jq -r '.events[] | select(.type=="store_code") | .attributes[] | select(.key=="code_id") | .value') + assert [ "$CODE_ID" -gt 0 ] + echo "# --> Contract uploaded with code ID: $CODE_ID" >&3 +} + +instantiate_contract() { + local init_msg=$1 + run_tx "Instantiating contract" wasm instantiate "$CODE_ID" "$init_msg" \ + --from "$USER_ADDR" --label "converter-test" --admin "$USER_ADDR" + CONTRACT_ADDR=$(docker exec "$CONTAINER_NAME" manifestd query tx "$TX_HASH" --node "$RPC" --output json | \ + jq -r '.events[] | select(.type=="wasm") | .attributes[] | select(.key=="_contract_address") | .value') + assert [ -n "$CONTRACT_ADDR" ] + echo "# --> Contract instantiated at: $CONTRACT_ADDR" >&3 +} + +grant_authz() { + local msg_type=$1 + run_tx "Granting authz for $msg_type" authz grant "$CONTRACT_ADDR" generic \ + --msg-type "$msg_type" --from "$USER_ADDR" +} + +execute_contract() { + local msg=$1 + local from=$2 + local amount=${3:-} # optional third argument + + echo "# --> Executing contract message" >&3 + + if [ -n "$amount" ]; then + run_tx "Executing contract (with funds)" wasm execute "$CONTRACT_ADDR" "$msg" \ + --from "$from" \ + --amount "$amount" + else + run_tx "Executing contract" wasm execute "$CONTRACT_ADDR" "$msg" \ + --from "$from" + fi +} diff --git a/e2e/tests/converter.bats b/e2e/tests/converter.bats new file mode 100644 index 0000000..381d4d9 --- /dev/null +++ b/e2e/tests/converter.bats @@ -0,0 +1,75 @@ +#!/usr/bin/env bats + +load '../test_helper/bats-support/load' +load '../test_helper/bats-assert/load' +load '../test_helper/common.sh' + +setup() { + export CHAIN_ID="test-1" + export RPC="http://localhost:26657" + export CONTAINER_NAME="e2e-manifest-ledger-1" + export WASM_FILE="artifacts/converter.wasm" + export USER_ADDR="manifest1hj5fveer5cjtn4wd6wstzugjfdxzl0xp8ws9ct" + export USER2_ADDR="manifest1efd63aw40lxf3n4mhf7dzhjkr453axurm6rp3z" + export POA_ADMIN_ADDR=$USER_ADDR + export RATE="2" + export SOURCE_DENOM="umfx" + export TARGET_DENOM="factory/manifest1afk9zr2hn2jsac63h4hm60vl9z3e5u69gndzf7c99cqge3vzwjzsfmy9qj/upwr" + export GAS_PRICES="0.0011umfx" + + run make build-opt + assert_success + assert [ -f "$WASM_FILE" ] + + run make e2e-chain-up + assert_success + sleep 5 +} + +teardown() { + [ "$BATS_TEST_COMPLETED" = "1" ] && make e2e-chain-down +} + +@test "converter end-to-end" { + store_contract + + INIT_MSG=$(jq -n --arg admin "$USER_ADDR" --arg poa "$POA_ADMIN_ADDR" \ + --arg rate "$RATE" --arg src "$SOURCE_DENOM" --arg tgt "$TARGET_DENOM" \ + '{"admin":$admin,"poa_admin":$poa,"rate":$rate,"source_denom":$src,"target_denom":$tgt,"paused":false}') + instantiate_contract "$INIT_MSG" + + grant_authz "/osmosis.tokenfactory.v1beta1.MsgMint" + grant_authz "/liftedinit.manifest.v1.MsgBurnHeldBalance" + + SOURCE_SUPPLY_BEFORE=$(query_json "Querying MFX total supply before conversion" bank total-supply-of "$SOURCE_DENOM" | jq -r '.amount.amount') + TARGET_SUPPLY_BEFORE=$(query_json "Querying PWR total supply before conversion" bank total-supply-of "$TARGET_DENOM" | jq -r '.amount.amount') + + execute_contract '{"convert":{}}' "$USER2_ADDR" "1000000$SOURCE_DENOM" + + PWR_BALANCE=$(query_json "Querying user2 PWR balance" bank balances "$USER2_ADDR" | jq -r '.balances[] | select(.denom=="'"$TARGET_DENOM"'") | .amount') + assert [ "$PWR_BALANCE" == "2000000" ] + + execute_contract '{"update_admin":{"admin":"'"$USER2_ADDR"'"}}' "$USER_ADDR" + execute_contract '{"update_config":{"config":{"rate":"3"}}}' "$USER2_ADDR" + + execute_contract '{"convert":{}}' "$USER2_ADDR" "1000000$SOURCE_DENOM" + PWR_BALANCE=$(query_json "Querying updated PWR balance" bank balances "$USER2_ADDR" | jq -r '.balances[] | select(.denom=="'"$TARGET_DENOM"'") | .amount') + assert [ "$PWR_BALANCE" == "5000000" ] + + execute_contract '{"update_config":{"config":{"paused":true}}}' "$USER2_ADDR" + run docker exec "$CONTAINER_NAME" manifestd tx wasm execute "$CONTRACT_ADDR" '{"convert":{}}' \ + --from "$USER2_ADDR" --home "/persistent/.manifest" --keyring-backend "test" \ + --amount "1000000$SOURCE_DENOM" --gas auto --gas-prices "$GAS_PRICES" \ + --chain-id "$CHAIN_ID" --node "$RPC" --yes --output json + assert_failure + + execute_contract '{"update_config":{"config":{"paused":false}}}' "$USER2_ADDR" + execute_contract '{"convert":{}}' "$USER2_ADDR" "1000000$SOURCE_DENOM" + PWR_BALANCE=$(query_json "Querying PWR balance after unpause" bank balances "$USER2_ADDR" | jq -r '.balances[] | select(.denom=="'"$TARGET_DENOM"'") | .amount') + assert [ "$PWR_BALANCE" == "8000000" ] + + run_tx "Migrating contract" wasm migrate "$CONTRACT_ADDR" "$CODE_ID" '{"migrate":{}}' --from "$USER_ADDR" + NOTE=$(docker exec "$CONTAINER_NAME" manifestd query tx "$TX_HASH" --node "$RPC" --output json | \ + jq -r '.events[] | select(.type=="wasm") | .attributes[] | select(.key=="note") | .value') + assert [ "$NOTE" == "already at latest version" ] +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..f77ddfc --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.86.0" +components = ["rustfmt", "clippy"] +targets = ["wasm32-unknown-unknown"] \ No newline at end of file