diff --git a/Cargo.lock b/Cargo.lock index 4de9fe0..dde8516 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1555,7 +1555,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "storage-outpost" -version = "0.1.0" +version = "0.2.0" dependencies = [ "cosmos-sdk-proto", "cosmwasm-schema", diff --git a/Cargo.toml b/Cargo.toml index 30191a2..d2eddc4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "storage-outpost" -version = "0.1.0" +version = "0.2.0" authors = ["Bi Phan ", "Serdar Turkmenafsar "] edition = "2021" diff --git a/artifacts/checksums.txt b/artifacts/checksums.txt index 7f7f1a6..590ec62 100644 --- a/artifacts/checksums.txt +++ b/artifacts/checksums.txt @@ -2,4 +2,4 @@ 894fda7fbfa805761ca6af408d20c148fa59ce0f9999d9c5909bfa8976a8943f basic_migration_v2.wasm a920122a00e82b445e6d5061f06018f330d334d61059b9da1069c65144e975d9 outpost_factory.wasm 2f0770fc02069a2c2034c5e27e57c10558ecd566fe2e7dfa0e549dc62440cf43 outpost_user.wasm -5e42a437754be7a3fc551a99cfcbbbf8a7b6c868a9d1ae8f7f6b1b20a950bf3b storage_outpost.wasm +c9c032f2244d3f2dbff5f1d2f51a90c9265a95859a0731f178e930ce70792cf0 storage_outpost.wasm diff --git a/artifacts/checksums_intermediate.txt b/artifacts/checksums_intermediate.txt index cd753ed..bb88f5d 100644 --- a/artifacts/checksums_intermediate.txt +++ b/artifacts/checksums_intermediate.txt @@ -1 +1 @@ -9bb5ca229a3180fc744c42fc8dde2a41ce291ebc9139bf02122fa68c77147c81 /target/wasm32-unknown-unknown/release/storage_outpost.wasm +b9230ba5637ab28778dd47d7a01ffe5f958593c41afeb37e2c95d1fd3f98c98b /target/wasm32-unknown-unknown/release/storage_outpost.wasm diff --git a/artifacts/storage_outpost.wasm b/artifacts/storage_outpost.wasm index f2511e5..6409606 100644 Binary files a/artifacts/storage_outpost.wasm and b/artifacts/storage_outpost.wasm differ diff --git a/e2e/interchaintest/filetree_post_key_test.go b/e2e/interchaintest/filetree_post_key_test.go index d5b6f7a..0f5bf11 100644 --- a/e2e/interchaintest/filetree_post_key_test.go +++ b/e2e/interchaintest/filetree_post_key_test.go @@ -128,6 +128,21 @@ func (s *ContractTestSuite) TestIcaContractExecutionTestWithFiletree() { s.Require().NoError(pubErr) s.Require().Equal(pubRes.PubKey.GetKey(), filetreeMsg.GetKey(), "Expected PubKey does not match the returned PubKey") + postMigrateMsg := testtypes.ExecuteMsg{ + SetDataAfterMigration: &testtypes.ExecuteMsg_SetDataAfterMigration{ + Data: "migration successful", + }, + } + + // Make sure migration data can be saved following a migration + err = s.Contract.Execute(ctx, wasmdUser.KeyName(), postMigrateMsg) + s.Require().NoError(err) + + // Query a PubKey + migrationRes, migrateErr := testsuite.GetMigrationData(ctx, s.ChainA, s.Contract.Address) + s.Require().NoError(migrateErr) + logger.LogInfo(migrationRes.Data) + // Query all Pubkeys // allRes, allErr := testsuite.AllPubKeys(ctx, s.ChainB) // s.Require().NoError(allErr) @@ -135,6 +150,6 @@ func (s *ContractTestSuite) TestIcaContractExecutionTestWithFiletree() { ) // implement mock query server - // time.Sleep(time.Duration(10) * time.Hour) + time.Sleep(time.Duration(10) * time.Hour) } diff --git a/e2e/interchaintest/logs/test.log b/e2e/interchaintest/logs/test.log index b5239b0..edcf14b 100644 --- a/e2e/interchaintest/logs/test.log +++ b/e2e/interchaintest/logs/test.log @@ -1,3 +1,4 @@ -INFO: 2024/10/17 18:29:41 The sender of instantiate is wasmd-localwasm-1-dxr -INFO: 2024/10/17 18:29:52 [0x140016b8100] -INFO: 2024/10/17 18:30:31 / +INFO: 2024/10/17 19:04:57 The sender of instantiate is wasmd-localwasm-1-hbq +INFO: 2024/10/17 19:05:09 [0x14001615200] +INFO: 2024/10/17 19:05:48 / +INFO: 2024/10/17 19:06:13 data:"\"migration successful\"" diff --git a/e2e/interchaintest/testsuite/wasm_query.go b/e2e/interchaintest/testsuite/wasm_query.go index 39d58f7..5c04823 100644 --- a/e2e/interchaintest/testsuite/wasm_query.go +++ b/e2e/interchaintest/testsuite/wasm_query.go @@ -150,3 +150,30 @@ func GetNote(ctx context.Context, chain *cosmos.CosmosChain, userAddress, outpos } return queryClient.SmartContractState(ctx, params) } + +func GetMigrationData(ctx context.Context, chain *cosmos.CosmosChain, outpostAddress string) (*wasmtypes.QuerySmartContractStateResponse, error) { + grpcConn, err := grpc.Dial( + chain.GetHostGRPCAddress(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + return nil, err + } + defer grpcConn.Close() + queryClient := wasmtypes.NewQueryClient(grpcConn) + + queryData := outposttypes.QueryMsg{ + GetMigrationData: &struct{}{}, + } + + queryDataBytes, err := json.Marshal(queryData) + if err != nil { + return nil, err + } + + params := &wasmtypes.QuerySmartContractStateRequest{ + Address: outpostAddress, + QueryData: queryDataBytes, + } + return queryClient.SmartContractState(ctx, params) +} diff --git a/e2e/interchaintest/types/msg.go b/e2e/interchaintest/types/msg.go index 01ecfe5..3f87fef 100644 --- a/e2e/interchaintest/types/msg.go +++ b/e2e/interchaintest/types/msg.go @@ -27,17 +27,19 @@ type Callback struct { // ExecuteMsg is the message to execute cw-ica-controller type ExecuteMsg struct { - CreateChannel *ExecuteMsg_CreateChannel `json:"create_channel,omitempty"` + SetDataAfterMigration *ExecuteMsg_SetDataAfterMigration `json:"set_data_after_migration,omitempty"` CreateTransferChannel *ExecuteMsg_CreateTransferChannel `json:"create_transfer_channel,omitempty"` SendCosmosMsgs *ExecuteMsg_SendCosmosMsgs `json:"send_cosmos_msgs,omitempty"` SendCustomIcaMessages *ExecuteMsg_SendCustomIcaMessages `json:"send_custom_ica_messages,omitempty"` UpdateCallbackAddress *ExecuteMsg_UpdateCallbackAddress `json:"update_callback_address,omitempty"` + CreateChannel *ExecuteMsg_CreateChannel `json:"create_channel,omitempty"` } // QueryMsg is the message to query cw-ica-controller type QueryMsg struct { GetChannel *struct{} `json:"get_channel,omitempty"` GetContractState *struct{} `json:"get_contract_state,omitempty"` + GetMigrationData *struct{} `json:"get_migration_data,omitempty"` Ownership *struct{} `json:"ownership,omitempty"` GetNote *GetNoteRequest `json:"get_note,omitempty"` } @@ -65,6 +67,10 @@ type ExecuteMsg_CreateChannel struct { ChannelOpenInitOptions *ChannelOpenInitOptions `json:"channel_open_init_options,omitempty"` } +type ExecuteMsg_SetDataAfterMigration struct { + Data string `json:"data,omitempty"` +} + // `CreateTransferChannel` is opening a transfer channel // for development purposees only. Not using ChannelOpenInitOptions type ExecuteMsg_CreateTransferChannel struct { diff --git a/src/contract.rs b/src/contract.rs index 9b18c80..04cc407 100644 --- a/src/contract.rs +++ b/src/contract.rs @@ -7,7 +7,8 @@ use crate::ibc::types::stargate::channel::new_ica_channel_open_init_cosmos_msg; use crate::types::keys::{self, CONTRACT_NAME, CONTRACT_VERSION}; use crate::types::msg::{OutpostFactoryExecuteMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; use crate::types::state::{ - self, CallbackCounter, ChannelState, ContractState, CALLBACK_COUNTER, CHANNEL_STATE, STATE, CHANNEL_OPEN_INIT_OPTIONS, ALLOW_CHANNEL_OPEN_INIT + self, CallbackCounter, ChannelState, ContractState, CALLBACK_COUNTER, CHANNEL_STATE, STATE, CHANNEL_OPEN_INIT_OPTIONS, ALLOW_CHANNEL_OPEN_INIT, + MIGRATION_DATA, }; use crate::types::ContractError; use crate::types::filetree::{MsgPostKey, MsgPostFile}; @@ -125,6 +126,7 @@ pub fn execute( } => { execute::send_cosmos_msgs(deps, env, info, messages, packet_memo, timeout_seconds) }, + ExecuteMsg::SetDataAfterMigration { data } => execute::save_data_after_migration(deps, env, info, data), } } @@ -137,6 +139,8 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { QueryMsg::GetChannel {} => to_json_binary(&query::channel(deps)?), QueryMsg::GetCallbackCounter {} => to_json_binary(&query::callback_counter(deps)?), QueryMsg::Ownership {} => to_json_binary(&query::get_owner(deps)?), + QueryMsg::GetMigrationData {} => to_json_binary(&query::migration_data(deps)?), + } } @@ -236,6 +240,18 @@ mod execute { let send_packet_msg = ica_packet.to_ibc_msg(&env, ica_info.channel_id, timeout_seconds)?; Ok(Response::default().add_message(send_packet_msg)) + } + + pub fn save_data_after_migration( + deps: DepsMut, + env: Env, + info: MessageInfo, + data: String, + ) -> Result { + + let _ = state::MIGRATION_DATA.save(deps.storage, &data); + + Ok(Response::new().add_attribute("method", "save_data_after_migration")) } } @@ -274,6 +290,11 @@ mod query { Err(StdError::generic_err("No owner found")) } } + + /// Returns the migration data + pub fn migration_data(deps: Deps) -> StdResult { + MIGRATION_DATA.load(deps.storage) + } } mod migrate { diff --git a/src/types/msg.rs b/src/types/msg.rs index d85c8d4..82804c5 100644 --- a/src/types/msg.rs +++ b/src/types/msg.rs @@ -61,6 +61,12 @@ pub enum ExecuteMsg { #[serde(skip_serializing_if = "Option::is_none")] timeout_seconds: Option, }, + + /// Save some arbitrary data to confirm migration success + SetDataAfterMigration { + /// Arbitary string + data: String, + }, } /// The outpost factory depends on the outpost, which causes a cyclic dependency if the outpost called @@ -95,7 +101,9 @@ pub enum QueryMsg { /// GetCallbackCounter returns the callback counter. #[returns(crate::types::state::CallbackCounter)] GetCallbackCounter {}, - + /// Return the migration data + #[returns(String)] + GetMigrationData {}, } /// The message to migrate this contract. diff --git a/src/types/state.rs b/src/types/state.rs index 28cdff3..65f2614 100644 --- a/src/types/state.rs +++ b/src/types/state.rs @@ -30,6 +30,10 @@ pub const ALLOW_CHANNEL_CLOSE_INIT: Item = Item::new("allow_channel_close_ /// The item used to store the successful and erroneous callbacks in store. pub const CALLBACK_COUNTER: Item = Item::new("callback_counter"); +/// Migration data that shows the migration succeeded +pub const MIGRATION_DATA: Item = Item::new("migration-data"); + + mod contract { use crate::ibc::types::metadata::TxEncoding;