Skip to content

Commit

Permalink
feat(cosmwasm): add core migration script (#3916)
Browse files Browse the repository at this point in the history
  • Loading branch information
benluelo authored Mar 3, 2025
2 parents 59e0f77 + 2676b05 commit 540e4f6
Show file tree
Hide file tree
Showing 14 changed files with 187 additions and 148 deletions.
100 changes: 68 additions & 32 deletions cosmwasm/cosmwasm.nix
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
ucs03 = ucs03-configs.cw20;
};
# lightclients = pkgs.lib.lists.remove "cometbls" (builtins.attrNames all-lightclients);
lightclients = [ ];
}
{
name = "union-testnet";
Expand Down Expand Up @@ -169,6 +170,26 @@
"state-lens-ics23-mpt"
];
}
{
name = "mantra-testnet";
rpc_url = "https://rpc.dukong.mantrachain.io/";
private_key = ''"$1"'';
gas_config = {
gas_price = "0.015";
gas_denom = "uom";
gas_multiplier = "1.4";
max_gas = 60000000;
};
apps = {
ucs03 = ucs03-configs.cw20;
};
bech32_prefix = "mantra";
lightclients = [
"cometbls"
"tendermint"
"state-lens-ics23-mpt"
];
}
];

# directory => {}
Expand Down Expand Up @@ -287,17 +308,21 @@
pkgs.writeText "contracts.json" (
builtins.toJSON {
core = ibc-union;
lightclient = pkgs.lib.mapAttrs' (n: v: {
name = v.client-type;
value = mk-lightclient n;
}) (builtins.filter ({ name, ... }: builtins.elem name lightclients) all-lightclients);
lightclient = builtins.listToAttrs (
map (
{ name, client-type, ... }:
{
name = client-type;
value = mk-lightclient name;
}
) (builtins.filter ({ name, ... }: builtins.elem name lightclients) all-lightclients)
);
app = apps;
}
);

chain-migration-scripts =
args@{
name,
lightclients,
apps,
private_key,
Expand All @@ -310,7 +335,7 @@
map (
lc:
let
name = "${args.name}-migrate-lightclient-${lc}";
name = "migrate-lightclient-${lc}-${args.name}";
in
{
inherit name;
Expand All @@ -330,7 +355,7 @@
migrate \
--rpc-url ${rpc_url} \
--address "$(echo "$ADDRESSES" | jq '.lightclient."${
(get-lightclient (lc: lc.name == name)).client-type
(get-lightclient (l: l.name == lc)).client-type
}"' -r)" \
--new-bytecode ${mk-lightclient lc} \
--private-key ${private_key} \
Expand All @@ -347,7 +372,7 @@
map (
app:
let
name = "${args.name}-migrate-app-${app}";
name = "migrate-app-${app}-${args.name}";
in
{
inherit name;
Expand Down Expand Up @@ -383,27 +408,37 @@
}
) (builtins.attrNames apps)
))
# // (map (
# _a:
# pkgs.writeShellApplication {
# name = "${name}-migrate-app-{a}";
# runtimeInputs = [ cosmwasm-deployer.packages.cosmwasm-deployer ];
# text = ''
# cosmwasm-deployer \
# addresses \
# ${
# pkgs.lib.strings.concatStrings (
# map (l: " --lightclient ${all-lightclients.${l}.client-type}") (builtins.attrNames all-lightclients)
# )
# } \
# ${
# pkgs.lib.strings.concatStrings (map (a: " --${all-apps.${a}.name}") (builtins.attrNames all-apps))
# } \
# --deployer "$1" ''${2+--output $2}
# '';
# }
# ) apps)
;
// (
let
name = "migrate-${args.name}-core";
in
{
${name} = pkgs.writeShellApplication {
inherit name;
runtimeInputs = [
ibc-union-contract-addresses
cosmwasm-deployer.packages.cosmwasm-deployer
];
text = ''
DEPLOYER=$(cosmwasm-deployer address-of-private-key --private-key ${private_key} --bech32-prefix ${bech32_prefix})
echo "deployer address: $DEPLOYER"
ADDRESSES=$(ibc-union-contract-addresses "$DEPLOYER")
RUST_LOG=info \
cosmwasm-deployer \
migrate \
--rpc-url ${rpc_url} \
--address "$(echo "$ADDRESSES" | jq '.core' -r)" \
--new-bytecode ${ibc-union} \
--private-key ${private_key} \
--gas-price ${toString gas_config.gas_price} \
--gas-denom ${toString gas_config.gas_denom} \
--gas-multiplier ${toString gas_config.gas_multiplier} \
--max-gas ${toString gas_config.max_gas} \
'';
};
}
);

ibc-union-contract-addresses = pkgs.writeShellApplication {
name = "ibc-union-contract-addresses";
Expand All @@ -422,7 +457,10 @@
};

get-lightclient =
f: pkgs.lib.lists.findSingle f (throw "not found") (throw "many found") all-lightclients;
f:
pkgs.lib.lists.findSingle f (throw "lightclient not found")
(throw "many matching lightclients found")
all-lightclients;

mk-lightclient =
name:
Expand Down Expand Up @@ -571,8 +609,6 @@
))
)
// (builtins.foldl' (a: b: a // b) { } (map chain-migration-scripts networks))
# // (dbg (chain-migration-scripts (builtins.elemAt networks 0)))
# // (dbg (chain-migration-scripts (builtins.elemAt networks 1)))
// derivation { name = "cosmwasm-scripts"; };
}
// cosmwasm-deployer.packages
Expand Down
7 changes: 5 additions & 2 deletions cosmwasm/ibc-union/core/light-client-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ pub trait IbcClient: Sized {
fn get_counterparty_chain_id(client_state: &Self::ClientState) -> String;

/// Get the status of the client
fn status(client_state: &Self::ClientState) -> Status;
fn status(ctx: IbcClientCtx<Self>, client_state: &Self::ClientState) -> Status;

/// Verify the initial state of the client
fn verify_creation(
Expand Down Expand Up @@ -266,7 +266,10 @@ pub fn query<T: IbcClient>(
let ibc_host = IBC_HOST.load(deps.storage)?;
let client_state =
read_client_state::<T>(deps.querier.into_empty(), &ibc_host, client_id)?;
let status = T::status(&client_state);
let status = T::status(
IbcClientCtx::new(client_id, ibc_host, deps, env),
&client_state,
);
to_json_binary(&status).map_err(Into::into)
}
QueryMsg::VerifyCreation {
Expand Down
2 changes: 1 addition & 1 deletion cosmwasm/ibc-union/core/msg/src/lightclient.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use unionlabs_primitives::Bytes;

#[derive(serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields, rename_all = "snake_case")]
pub enum Status {
Active,
Expand Down
11 changes: 11 additions & 0 deletions cosmwasm/ibc-union/core/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,17 @@ fn update_client(
// Ugly hack to allow for >64K messages (not configurable) to be threaded for the query.
// See https://github.com/CosmWasm/cosmwasm/blob/e17ecc44cdebc84de1caae648c7a4f4b56846f8f/packages/vm/src/imports.rs#L47
QUERY_STORE.save(deps.storage, &client_message.into())?;

let status = query_light_client::<Status>(
deps.as_ref(),
client_impl.clone(),
LightClientQuery::GetStatus { client_id },
)?;

if !matches!(status, Status::Active) {
return Err(ContractError::ClientNotActive { client_id, status });
}

let update = query_light_client::<VerifyClientMessageUpdate>(
deps.as_ref(),
client_impl,
Expand Down
6 changes: 6 additions & 0 deletions cosmwasm/ibc-union/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod state;
mod tests;

use cosmwasm_std::{Addr, StdError};
use ibc_union_msg::lightclient::Status;
use ibc_union_spec::types::{ChannelState, ConnectionState};
use thiserror::Error;
use unionlabs::primitives::Bytes;
Expand Down Expand Up @@ -130,6 +131,11 @@ pub enum ContractError {
query: Box<ibc_union_msg::lightclient::QueryMsg>,
error: StdError,
},
#[error(
"{} client {client_id} is not active (status {status:?})",
ContractErrorKind::from(self)
)]
ClientNotActive { client_id: u32, status: Status },
}

impl ContractErrorKind {
Expand Down
9 changes: 4 additions & 5 deletions cosmwasm/ibc-union/lightclient/arbitrum/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,7 @@ impl IbcClient for ArbitrumLightClient {
ctx: IbcClientCtx<Self>,
header: Self::Header,
_caller: cosmwasm_std::Addr,
) -> Result<
(u64, Self::ClientState, Self::ConsensusState),
ibc_union_light_client::IbcClientError<Self>,
> {
) -> Result<(u64, Self::ClientState, Self::ConsensusState), IbcClientError<Self>> {
let mut client_state = ctx.read_self_client_state()?;
let l1_consensus_state = ctx
.read_consensus_state::<EthereumLightClient>(
Expand Down Expand Up @@ -97,7 +94,9 @@ impl IbcClient for ArbitrumLightClient {
Err(Error::Unimplemented.into())
}

fn status(client_state: &Self::ClientState) -> Status {
fn status(ctx: IbcClientCtx<Self>, client_state: &Self::ClientState) -> Status {
let _ = ctx;

if client_state.frozen_height.height() != 0 {
Status::Frozen
} else {
Expand Down
30 changes: 13 additions & 17 deletions cosmwasm/ibc-union/lightclient/berachain/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use beacon_api_types::{ExecutionPayloadHeaderSsz, Mainnet};
use berachain_light_client_types::{ClientState, ConsensusState, Header};
use cosmwasm_std::Empty;
use ethereum_light_client_types::StorageProof;
use ibc_union_light_client::IbcClient;
use ibc_union_light_client::{IbcClient, IbcClientCtx, IbcClientError};
use ibc_union_msg::lightclient::{Status, VerifyCreationResponseEvent};
use tendermint_light_client::client::TendermintLightClient;
use unionlabs::{
Expand Down Expand Up @@ -33,12 +33,12 @@ impl IbcClient for BerachainLightClient {
type StorageProof = StorageProof;

fn verify_membership(
ctx: ibc_union_light_client::IbcClientCtx<Self>,
ctx: IbcClientCtx<Self>,
height: u64,
key: Vec<u8>,
storage_proof: Self::StorageProof,
value: Vec<u8>,
) -> Result<(), ibc_union_light_client::IbcClientError<Self>> {
) -> Result<(), IbcClientError<Self>> {
let consensus_state = ctx.read_self_consensus_state(height)?;
ethereum_light_client::client::verify_membership(
key,
Expand All @@ -51,11 +51,11 @@ impl IbcClient for BerachainLightClient {
}

fn verify_non_membership(
ctx: ibc_union_light_client::IbcClientCtx<Self>,
ctx: IbcClientCtx<Self>,
height: u64,
key: Vec<u8>,
storage_proof: Self::StorageProof,
) -> Result<(), ibc_union_light_client::IbcClientError<Self>> {
) -> Result<(), IbcClientError<Self>> {
let consensus_state = ctx.read_self_consensus_state(height)?;
ethereum_light_client::client::verify_non_membership(
key,
Expand All @@ -78,7 +78,9 @@ impl IbcClient for BerachainLightClient {
client_state.chain_id.to_string()
}

fn status(_client_state: &Self::ClientState) -> Status {
fn status(ctx: IbcClientCtx<Self>, client_state: &Self::ClientState) -> Status {
let _ = client_state;
let _ = ctx;
// FIXME: expose the ctx to this call to allow threading this call to L1
// client. generally, we want to thread if a client is an L2 so always
// provide the ctx?
Expand All @@ -88,22 +90,16 @@ impl IbcClient for BerachainLightClient {
fn verify_creation(
_client_state: &Self::ClientState,
_consensus_state: &Self::ConsensusState,
) -> Result<
Option<Vec<VerifyCreationResponseEvent>>,
ibc_union_light_client::IbcClientError<Self>,
> {
) -> Result<Option<Vec<VerifyCreationResponseEvent>>, IbcClientError<Self>> {
Ok(None)
}

// TODO: rearrange to avoid the clones
fn verify_header(
ctx: ibc_union_light_client::IbcClientCtx<Self>,
ctx: IbcClientCtx<Self>,
header: Self::Header,
_caller: cosmwasm_std::Addr,
) -> Result<
(u64, Self::ClientState, Self::ConsensusState),
ibc_union_light_client::IbcClientError<Self>,
> {
) -> Result<(u64, Self::ClientState, Self::ConsensusState), IbcClientError<Self>> {
let mut client_state = ctx.read_self_client_state()?;

// 1. extract L1 state
Expand Down Expand Up @@ -156,9 +152,9 @@ impl IbcClient for BerachainLightClient {
}

fn misbehaviour(
_ctx: ibc_union_light_client::IbcClientCtx<Self>,
_ctx: IbcClientCtx<Self>,
_misbehaviour: Self::Misbehaviour,
) -> Result<Self::ClientState, ibc_union_light_client::IbcClientError<Self>> {
) -> Result<Self::ClientState, IbcClientError<Self>> {
Err(Error::Unimplemented.into())
}
}
Loading

0 comments on commit 540e4f6

Please sign in to comment.