Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cli for migration #1527

Merged
merged 14 commits into from
Sep 5, 2023
Binary file added docs/upgrades/1.11/contract.wasm
Binary file not shown.
58 changes: 58 additions & 0 deletions docs/upgrades/1.11/docker-compose-111.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# docker compose file that sets up a network for beta testing

version: "3"

services:
bootstrap:
image: ghcr.io/scrtlabs/localsecret:v1.10.0
container_name: bootstrap
volumes:
- /tmp/secretd:/root/.secretd
- /tmp/secretcli:/root/.secretcli
stdin_open: true
tty: true
environment:
- http_proxy
- https_proxy
- SECRET_NODE_TYPE=BOOTSTRAP
- LOG_LEVEL=trace
- CHAINID=secretdev-1
- SGX_MODE=SW
expose:
- 26656
- 26657
ports:
- "5000:5000"
entrypoint: /bin/bash

node:
image: ghcr.io/scrtlabs/localsecret:v1.10.0
container_name: node
depends_on:
- bootstrap
volumes:
- /tmp/secretd:/tmp/.secretd
- /tmp/secretcli:/root/.secretcli
stdin_open: true
tty: true
ports:
- "1317:1317"
- "9091:9091"
environment:
- http_proxy
- https_proxy
- SECRET_NODE_TYPE=node
- LOG_LEVEL=trace
- CHAINID=secretdev-1
- RPC_URL=bootstrap:26657
- PERSISTENT_PEERS=115aa0a629f5d70dd1d464bc7e42799e00f4edae@bootstrap:26656
- FAUCET_URL=bootstrap:5000
- SCRT_SGX_STORAGE=/root
- SGX_MODE=SW
entrypoint: /bin/bash
deploy:
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 10
window: 123s
68 changes: 68 additions & 0 deletions docs/upgrades/1.11/node_init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env bash

set -euvo pipefail

# init the node
# rm -rf ~/.secret*
#secretd config chain-id enigma-testnet
secretd config output json
#secretd config indent true
#secretd config trust-node true
#secretd config keyring-backend test
# rm -rf ~/.secretd

mkdir -p /root/.secretd/.node
secretd config keyring-backend test
secretd config node http://bootstrap:26657
secretd config chain-id secretdev-1

mkdir -p /root/.secretd/.node

secretd init "$(hostname)" --chain-id secretdev-1 || true

PERSISTENT_PEERS=115aa0a629f5d70dd1d464bc7e42799e00f4edae@bootstrap:26656

sed -i 's/persistent_peers = ""/persistent_peers = "'$PERSISTENT_PEERS'"/g' ~/.secretd/config/config.toml
sed -i 's/trust_period = "168h0m0s"/trust_period = "168h"/g' ~/.secretd/config/config.toml
echo "Set persistent_peers: $PERSISTENT_PEERS"

echo "Waiting for bootstrap to start..."
sleep 20

secretd q block 1

cp /tmp/.secretd/keyring-test /root/.secretd/ -r

# MASTER_KEY="$(secretd q register secret-network-params 2> /dev/null | cut -c 3- )"

#echo "Master key: $MASTER_KEY"

SGX_MODE=SW secretd init-enclave --reset

PUBLIC_KEY=$(SGX_MODE=SW secretd parse /root/attestation_cert.der | cut -c 3- )

echo "Public key: $PUBLIC_KEY"

SGX_MODE=SW secretd parse /root/attestation_cert.der
cat /root/attestation_cert.der
tx_hash="$(SGX_MODE=SW secretd tx register auth /root/attestation_cert.der -y --from a --gas-prices 0.25uscrt | jq -r '.txhash')"

#secretd q tx "$tx_hash"
sleep 15
SGX_MODE=SW secretd q tx "$tx_hash"

SEED="$(SGX_MODE=SW secretd q register seed "$PUBLIC_KEY" | cut -c 3-)"
echo "SEED: $SEED"
#exit

SGX_MODE=SW secretd q register secret-network-params

SGX_MODE=SW secretd configure-secret node-master-key.txt "$SEED"

cp /tmp/.secretd/config/genesis.json /root/.secretd/config/genesis.json

SGX_MODE=SW secretd validate-genesis

RUST_BACKTRACE=1 SGX_MODE=SW secretd start --rpc.laddr tcp://0.0.0.0:26657

# ./wasmi-sgx-test.sh
138 changes: 138 additions & 0 deletions docs/upgrades/1.11/test-v1.11-upgrade-handler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# How to test the v1.11 upgrade with LocalSecret

Always work in docs directory

## Step 1

Start a v1.10.0 chain.

```bash
docker compose -f docker-compose-111.yml up -d
docker cp node_init.sh node:/root/
```

On one terminal window:

```bash
docker exec -it bootstrap bash
./bootstrap_init.sh
```

On another terminal window

```bash
docker exec -it node bash
chmod 0777 node_init.sh
./node_init.sh
```

## Step 2 (Test basic contract)

### Copy the suplied contract to the docker

```bash
docker cp ./contract.wasm node:/root/
```

### Access node docker

```bash
docker exec -it node bash
```

### Instantiate a contract and interact with him

```bash
secretd config node http://0.0.0.0:26657
secretd tx compute store contract.wasm --from a --gas 5000000 -y
sleep 5
INIT='{"counter":{"counter":10, "expires":100000}}'
secretd tx compute instantiate 1 "$INIT" --from a --label "c" -y
sleep 5
ADDR=`secretd q compute list-contract-by-code 1 | jq -r '.[0].contract_address'`

secretd tx compute execute $ADDR '{"increment":{"addition": 13}}' --from a -y
sleep 5
secretd query compute query $ADDR '{"get": {}}'
```

Expected result should be:
{"get":{"count":23}}

## Step 4

Propose a software upgrade on the v1.10 chain.

```bash
# 30 blocks (3 minutes) until upgrade block
UPGRADE_BLOCK="$(docker exec node bash -c 'secretd status | jq "(.SyncInfo.latest_block_height | tonumber) + 30"')"

# Propose upgrade
PROPOSAL_ID="$(docker exec node bash -c "secretd tx gov submit-proposal software-upgrade v1.11 --upgrade-height $UPGRADE_BLOCK --title blabla --description yolo --deposit 100000000uscrt --from a -y -b block | jq '.logs[0].events[] | select(.type == \"submit_proposal\") | .attributes[] | select(.key == \"proposal_id\") | .value | tonumber'")"

# Vote yes (voting period is 90 seconds)
docker exec node bash -c "secretd tx gov vote ${PROPOSAL_ID} yes --from a -y -b block"

echo "PROPOSAL_ID = ${PROPOSAL_ID}"
echo "UPGRADE_BLOCK = ${UPGRADE_BLOCK}"
```

## Step 5

Apply the upgrade.

Wait until you see `ERR CONSENSUS FAILURE!!! err="UPGRADE \"v1.11\" NEEDED at height` in BOTH of the logs,
then, from the root directory of the project, run:

```bash
FEATURES="light-client-validation,random" SGX_MODE=SW make build-linux

# Copy binaries from host to current v1.8 chain

docker exec bootstrap bash -c 'rm -rf /tmp/upgrade-bin && mkdir -p /tmp/upgrade-bin'
docker exec node bash -c 'rm -rf /tmp/upgrade-bin && mkdir -p /tmp/upgrade-bin'

docker cp usr/local/bin/secretd bootstrap:/tmp/upgrade-bin
docker cp usr/lib/librust_cosmwasm_enclave.signed.so bootstrap:/tmp/upgrade-bin
docker cp usr/lib/libgo_cosmwasm.so bootstrap:/tmp/upgrade-bin
docker cp usr/local/bin/secretd node:/tmp/upgrade-bin
docker cp usr/lib/librust_cosmwasm_enclave.signed.so node:/tmp/upgrade-bin
docker cp usr/lib/libgo_cosmwasm.so node:/tmp/upgrade-bin
# These two should be brought from the external repo or from a previous localsecret
docker cp usr/lib/librandom_api.so node:/usr/lib
docker cp usr/lib/tendermint_enclave.signed.so node:/usr/lib

docker exec node bash -c 'pkill -9 secretd'

docker exec bootstrap bash -c 'cat /tmp/upgrade-bin/librust_cosmwasm_enclave.signed.so > /usr/lib/librust_cosmwasm_enclave.signed.so'
docker exec bootstrap bash -c 'cat /tmp/upgrade-bin/libgo_cosmwasm.so > /usr/lib/libgo_cosmwasm.so'
docker exec node bash -c 'cat /tmp/upgrade-bin/secretd > /usr/bin/secretd'
docker exec node bash -c 'cat /tmp/upgrade-bin/librust_cosmwasm_enclave.signed.so > /usr/lib/librust_cosmwasm_enclave.signed.so'
docker exec node bash -c 'cat /tmp/upgrade-bin/libgo_cosmwasm.so > /usr/lib/libgo_cosmwasm.so'


rm -rf /tmp/upgrade-bin && mkdir -p /tmp/upgrade-bin
docker cp bootstrap:/root/.secretd/config/priv_validator_key.json /tmp/upgrade-bin/.
docker cp /tmp/upgrade-bin/priv_validator_key.json node:/root/.secretd/config/priv_validator_key.json
```

Then, restart secretd from the node you just killed:

```bash
source /opt/sgxsdk/environment && RUST_BACKTRACE=1 LOG_LEVEL="trace" secretd start --rpc.laddr tcp://0.0.0.0:26657
```

You should see `INF applying upgrade "v1.11" at height` in the logs, following by blocks continute to stream.

## Test that the contract is still there

### Query the value of the counter

```bash
secretd query compute query $ADDR '{"get": {}}'
```

Expected result should be:
{"get":{"count":23}}

## Test contract upgrade
File renamed without changes.
File renamed without changes.
33 changes: 30 additions & 3 deletions x/compute/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const (
flagProposalType = "type"
flagIoMasterKey = "enclave-key"
flagCodeHash = "code-hash"
flagAdmin = "admin"
)

// GetTxCmd returns the transaction commands for this module
Expand Down Expand Up @@ -127,7 +128,7 @@ func parseStoreCodeArgs(args []string, cliCtx client.Context, flags *flag.FlagSe
// InstantiateContractCmd will instantiate a contract from previously uploaded code.
func InstantiateContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "instantiate [code_id_int64] [json_encoded_init_args] --label [text] --amount [coins,optional]",
Use: "instantiate [code_id_int64] [json_encoded_init_args] --label [text] --amount [coins,optional] --admin [admin_addr_bech32,optional]",
Short: "Instantiate a wasm contract",
Aliases: []string{"init"},
Args: cobra.ExactArgs(2),
Expand All @@ -153,6 +154,7 @@ func InstantiateContractCmd() *cobra.Command {
"io-master-key.txt file, which you can get using the command `secretcli q register secret-network-params` ")
cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation")
cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists")
cmd.Flags().String(flagAdmin, "", "Optional: Bech32 address of the admin of the contract")
flags.AddTxFlagsToCmd(cmd)
return cmd
}
Expand Down Expand Up @@ -234,6 +236,11 @@ func parseInstantiateArgs(args []string, cliCtx client.Context, initFlags *flag.
return types.MsgInstantiateContract{}, err
}

admin, err := initFlags.GetString(flagAdmin)
if err != nil {
return types.MsgInstantiateContract{}, fmt.Errorf("Admin: %s", err)
}

// build and sign the transaction, then broadcast to Tendermint
msg := types.MsgInstantiateContract{
Sender: cliCtx.GetFromAddress(),
Expand All @@ -243,6 +250,16 @@ func parseInstantiateArgs(args []string, cliCtx client.Context, initFlags *flag.
InitFunds: amount,
InitMsg: encryptedMsg,
}

if admin != "" {
_, err = sdk.AccAddressFromBech32(admin)
if err != nil {
return types.MsgInstantiateContract{}, fmt.Errorf("Admint address is not in bech32 format: %s", err)
}

msg.Admin = admin
}

return msg, nil
}

Expand Down Expand Up @@ -445,14 +462,24 @@ func parseMigrateContractArgs(args []string, cliCtx client.Context) (types.MsgMi
if err != nil {
return types.MsgMigrateContract{}, sdkerrors.Wrap(err, "code id")
}
migrateMsg := types.SecretMsg{}

migrateMsg := args[2]
migrateMsg.CodeHash, err = GetCodeHashByCodeId(cliCtx, args[1])
if err != nil {
return types.MsgMigrateContract{}, sdkerrors.Wrap(err, "code hash")
}

migrateMsg.Msg = []byte(args[2])
wasmCtx := wasmUtils.WASMContext{CLIContext: cliCtx}
encryptedMsg, err := wasmCtx.Encrypt(migrateMsg.Serialize())
if err != nil {
return types.MsgMigrateContract{}, sdkerrors.Wrap(err, "encrypt")
}
msg := types.MsgMigrateContract{
Sender: cliCtx.GetFromAddress().String(),
Contract: args[0],
CodeID: codeID,
Msg: []byte(migrateMsg),
Msg: encryptedMsg,
}
return msg, nil
}
Expand Down
Loading