Skip to content

Commit

Permalink
Integrate contract migration (#160)
Browse files Browse the repository at this point in the history
* Integrate contract migration
* Migrate the contract before the integration tests start
* Add migration integration test
* Add migration CLI and instructions
  • Loading branch information
dzmitryhil authored Mar 18, 2024
1 parent 993f8ed commit 8e30198
Show file tree
Hide file tree
Showing 24 changed files with 371 additions and 71 deletions.
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 ]
pull_request:
branches: [ "master" ]
branches: [ master ]
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/relayer-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,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=v1.1.0

###############################################################################
### Build ###
Expand Down Expand Up @@ -138,6 +139,11 @@ restart-bridge-znet-env:
crust znet start --profiles=bridge-xrpl
docker compose -p bridge-znet -f ./infra/composer/docker-compose.yaml up -d

.PHONY: download-released-contract
download-released-contract:
mkdir -p $(BUILD_DIR)
curl --fail -LJ -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
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 (
ContractFilePathV110 = "../../build/coreumbridge_xrpl_v1.1.0.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 := DeployAndInstantiateContractV110(
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)
}

// DeployAndInstantiateContractV110 deploys and instantiates the mainnet version of the contract.
func DeployAndInstantiateContractV110(
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, ContractFilePathV110), 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
4 changes: 2 additions & 2 deletions 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 Expand Up @@ -309,7 +309,7 @@ func TestKeysRotationWithProhibitedAddresses(t *testing.T) {
ctx, chains := integrationtests.NewTestingContext(t)

initialRelayers := genRelayers(ctx, t, chains, 1)
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.DeployAndInstantiateContractV110(
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

0 comments on commit 8e30198

Please sign in to comment.