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

Integrate contract migration #160

Merged
merged 13 commits into from
Mar 18, 2024
4 changes: 2 additions & 2 deletions .github/workflows/contract-ci.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: contract-ci
on:
push:
branches: [ "master" ]
branches: [ master, migration ]
pull_request:
branches: [ "master" ]
branches: [ master, migration ]
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/relayer-ci.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: relayer-ci
on:
push:
branches: [ master ]
branches: [ master, migration ]
pull_request:
branches: [ master ]
branches: [ master, migration ]
workflow_dispatch:

jobs:
Expand Down Expand Up @@ -119,6 +119,10 @@ jobs:
run: make build-contract
working-directory: ./coreumbridge-xrpl
if: ${{ matrix.build-contract }}
- name: Download released wasm contract
run: make download-released-contract
if: ${{ matrix.build-contract }}
working-directory: ./coreumbridge-xrpl
- name: Build dev environment
run: make build-dev-env
working-directory: ./coreumbridge-xrpl
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ LD_FLAGS:="-extldflags=-static \
GOOS?=
GOARCH?=
BINARY_NAME?=coreumbridge-xrpl-relayer
RELEASE_VERSION=v0.0.2

###############################################################################
### Build ###
Expand Down Expand Up @@ -123,6 +124,11 @@ restart-dev-env:
build-dev-env:
crust build/crust build/znet images/cored

.PHONY: download-released-contract
download-released-contract:
mkdir -p $(BUILD_DIR)
curl --fail -o $(BUILD_DIR)/coreumbridge_xrpl_$(RELEASE_VERSION).wasm https://github.com/CoreumFoundation/coreumbridge-xrpl/releases/download/$(RELEASE_VERSION)/coreumbridge_xrpl.wasm

.PHONY: smoke
smoke:
make lint-contract
Expand Down
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ The `coreum-relayer` and `xrpl-relayer` are key names set by default in the `rel
to update them, then updated them in the `relayer.yaml` as well.

Or import the existing mnemonics:

```bash
coreumbridge-xrpl-relayer keys-coreum add coreum-relayer --recover

Expand Down Expand Up @@ -218,3 +219,33 @@ docker restart coreumbridge-xrpl-relayer && docker attach coreumbridge-xrpl-rela
```

Once you are attached, press any key and enter the keyring password.

### Migrate contract

#### Download new version of the contract

Download new version from the [Releases page](https://github.com/CoreumFoundation/coreumbridge-xrpl/releases) and store
locally.

#### Deploy new version of the contract

Execute the deployment command

```bash
coreumbridge-xrpl-relayer deploy-contract /path/to/wasm/contrac --key-name deployer
```

The `deployer` can be any account.

The command will provide and output with the new code ID. Use that code ID for the next command

#### Execute the migration

Execute the migration command

```bash
export NEW_CODE_ID={Code ID from previous command}
coreumbridge-xrpl-relayer migrate-contract $NEW_CODE_ID --key-name owner
```

Only admin is authorized to call that command.
1 change: 1 addition & 0 deletions contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ pub mod state;
mod tests;
pub mod tickets;
pub mod token;
pub mod migration;
24 changes: 24 additions & 0 deletions contract/src/migration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::error::ContractError;

use cosmwasm_std::entry_point;
use cosmwasm_std::{
DepsMut, Env, Response, StdError,
};

use cw2::set_contract_version;

const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

use crate::msg::{MigrateMsg};

#[entry_point]
pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
let ver = cw2::get_contract_version(deps.storage)?;
if ver.contract != CONTRACT_NAME {
return Err(StdError::generic_err("Can only upgrade from same contract type").into());
}
// TODO Add migration logic, and version validation
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
Ok(Response::default())
}
3 changes: 3 additions & 0 deletions contract/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ pub struct InstantiateMsg {
pub xrpl_base_fee: u64,
}

#[cw_serde]
pub struct MigrateMsg {}

#[cw_ownable_execute]
#[cw_serde]
pub enum ExecuteMsg {
Expand Down
59 changes: 53 additions & 6 deletions integration-tests/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,55 @@ import (
)

// CompiledContractFilePath is bridge contract file path.
const CompiledContractFilePath = "../../build/coreumbridge_xrpl.wasm"
const (
ContractFilePathV002 = "../../build/coreumbridge_xrpl_v0.0.2.wasm"
CompiledContractFilePath = "../../build/coreumbridge_xrpl.wasm"
)

// DeployInstantiateAndMigrateContract deploys and instantiates the mainnet version of the contract and applies
// migration.
func DeployInstantiateAndMigrateContract(
ctx context.Context,
t *testing.T,
chains Chains,
relayers []coreum.Relayer,
evidenceThreshold uint32,
usedTicketSequenceThreshold uint32,
trustSetLimitAmount sdkmath.Int,
bridgeXRPLAddress string,
xrplBaseFee uint32,
) (sdk.AccAddress, *coreum.ContractClient) {
t.Helper()

// DeployAndInstantiateContract deploys and instantiates the contract.
func DeployAndInstantiateContract(
owner, contractClient := DeployAndInstantiateContrantV002(
ctx,
t,
chains,
relayers,
evidenceThreshold,
usedTicketSequenceThreshold,
trustSetLimitAmount,
bridgeXRPLAddress,
xrplBaseFee,
)

MigrateContract(ctx, t, contractClient, owner)

return owner, contractClient
}

// MigrateContract migrates the contract to the compiled version.
func MigrateContract(ctx context.Context, t *testing.T, contractClient *coreum.ContractClient, owner sdk.AccAddress) {
t.Helper()

_, codeID, err := contractClient.DeployContract(ctx, owner, readBuiltContract(t, CompiledContractFilePath))
require.NoError(t, err)
_, err = contractClient.MigrateContract(ctx, owner, codeID)
require.NoError(t, err)
}

// DeployAndInstantiateContrantV002 deploys and instantiates the mainnet version of the contract.
func DeployAndInstantiateContrantV002(
ctx context.Context,
t *testing.T,
chains Chains,
Expand Down Expand Up @@ -54,18 +99,20 @@ func DeployAndInstantiateContract(
BridgeXRPLAddress: bridgeXRPLAddress,
XRPLBaseFee: xrplBaseFee,
}
contractAddress, err := contractClient.DeployAndInstantiate(ctx, owner, readBuiltContract(t), instantiationCfg)
contractAddress, err := contractClient.DeployAndInstantiate(
ctx, owner, readBuiltContract(t, ContractFilePathV002), instantiationCfg,
)
require.NoError(t, err)

require.NoError(t, contractClient.SetContractAddress(contractAddress))

return owner, contractClient
}

func readBuiltContract(t *testing.T) []byte {
func readBuiltContract(t *testing.T, path string) []byte {
t.Helper()

body, err := os.ReadFile(CompiledContractFilePath)
body, err := os.ReadFile(path)
require.NoError(t, err)

return body
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestCancelPendingOperation(t *testing.T) {
Amount: issueFee.Amount.Add(sdkmath.NewIntWithDecimal(1, 7)),
})

owner, contractClient := integrationtests.DeployAndInstantiateContract(
owner, contractClient := integrationtests.DeployInstantiateAndMigrateContract(
ctx,
t,
chains,
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/contract/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestDeployAndInstantiateContract(t *testing.T) {

xrplBaseFee := uint32(10)
usedTicketSequenceThreshold := uint32(10)
owner, contractClient := integrationtests.DeployAndInstantiateContract(
owner, contractClient := integrationtests.DeployInstantiateAndMigrateContract(
ctx,
t,
chains,
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/contract/halting_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestBridgeHalting(t *testing.T) {

xrplBridgeAddress := xrpl.GenPrivKeyTxSigner().Account()
xrplBaseFee := uint32(10)
owner, contractClient := integrationtests.DeployAndInstantiateContract(
owner, contractClient := integrationtests.DeployInstantiateAndMigrateContract(
ctx,
t,
chains,
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/contract/keys_rotation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestKeysRotationWithRecovery(t *testing.T) {

xrplBridgeAddress := xrpl.GenPrivKeyTxSigner().Account()
xrplBaseFee := uint32(10)
owner, contractClient := integrationtests.DeployAndInstantiateContract(
owner, contractClient := integrationtests.DeployInstantiateAndMigrateContract(
ctx,
t,
chains,
Expand Down
50 changes: 50 additions & 0 deletions integration-tests/contract/migration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//go:build integrationtests
// +build integrationtests

package contract_test

import (
"testing"

wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
"github.com/stretchr/testify/require"

integrationtests "github.com/CoreumFoundation/coreumbridge-xrpl/integration-tests"
"github.com/CoreumFoundation/coreumbridge-xrpl/relayer/xrpl"
)

func TestContractMigration(t *testing.T) {
t.Parallel()

ctx, chains := integrationtests.NewTestingContext(t)
relayers := genRelayers(ctx, t, chains, 2)

wasmClient := wasmtypes.NewQueryClient(chains.Coreum.ClientContext)

xrplBridgeAddress := xrpl.GenPrivKeyTxSigner().Account()
xrplBaseFee := uint32(10)
owner, contractClient := integrationtests.DeployAndInstantiateContrantV002(
ctx,
t,
chains,
relayers,
uint32(len(relayers)),
5,
defaultTrustSetLimitAmount,
xrplBridgeAddress.String(),
xrplBaseFee,
)

contractInfoBeforeMigration, err := wasmClient.ContractInfo(ctx, &wasmtypes.QueryContractInfoRequest{
Address: contractClient.GetContractAddress().String(),
})
require.NoError(t, err)

integrationtests.MigrateContract(ctx, t, contractClient, owner)

contractInfoAfterMigration, err := wasmClient.ContractInfo(ctx, &wasmtypes.QueryContractInfoRequest{
Address: contractClient.GetContractAddress().String(),
})
require.NoError(t, err)
require.NotEqual(t, contractInfoBeforeMigration.CodeID, contractInfoAfterMigration.CodeID)
}
2 changes: 1 addition & 1 deletion integration-tests/contract/ownership_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestChangeContractOwnership(t *testing.T) {

relayers := genRelayers(ctx, t, chains, 1)

owner, contractClient := integrationtests.DeployAndInstantiateContract(
owner, contractClient := integrationtests.DeployInstantiateAndMigrateContract(
ctx,
t,
chains,
Expand Down
Loading
Loading