Skip to content

Commit

Permalink
Merge pull request #1527 from scrtlabs/add-cli-for-migration
Browse files Browse the repository at this point in the history
Add cli for migration
  • Loading branch information
liorbond authored Sep 5, 2023
2 parents 3ba2ae3 + 6328635 commit 6e5f5c4
Show file tree
Hide file tree
Showing 10 changed files with 294 additions and 3 deletions.
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.
File renamed without changes.
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

0 comments on commit 6e5f5c4

Please sign in to comment.