diff --git a/x/compute/internal/keeper/secret_contracts_test.go b/x/compute/internal/keeper/secret_contracts_test.go index 084a823c2..46df384de 100644 --- a/x/compute/internal/keeper/secret_contracts_test.go +++ b/x/compute/internal/keeper/secret_contracts_test.go @@ -3516,6 +3516,40 @@ type v1QueryResponse struct { Get GetResponse `json:"get"` } +type EnvResponse struct { + Height int64 `json:"height"` + Time uint64 `json:"time"` + ChainID string `json:"chain_id"` + ContractAddress string `json:"contract_address"` + ContractCodeHash string `json:"code_hash"` +} +type v1GetEnvResponse struct { + Get EnvResponse `json:"get_env_params"` +} + +type MessageInfoResponse struct { + Sender string `json:"sender"` + Funds sdk.Coins `json:"funds"` +} + +type V1MessageInfoResponse struct { + Get MessageInfoResponse `json:"get_msg_info"` +} + +type V010EnvResponse struct { + Height int64 `json:"height"` + ChainID string `json:"chain_id"` + ContractAddress string `json:"contract_address"` + ContractKey string `json:"contract_key"` + ContractCodeHash string `json:"contract_code_hash"` + Time uint64 `json:"time"` + Sender string `json:"sender"` + SentFunds sdk.Coins `json:"sent_funds"` +} +type V010GetEnvResponse struct { + Get V010EnvResponse `json:"get_env_params"` +} + func TestV1EndpointsSanity(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/v1-sanity-contract/v1-contract.wasm", sdk.NewCoins()) @@ -3552,6 +3586,92 @@ func TestV1QueryWorksWithEnv(t *testing.T) { require.Equal(t, uint32(0), resp.Get.Count) } +func TestV010EnvParams(t *testing.T) { + coins := sdk.NewCoins() + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/test-contract/contract.wasm", coins) + + _, _, contractAddress, _, initErr := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"nop":{}}`, true, false, defaultGasForTests) + require.Empty(t, initErr) + + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 10) + _, _, data, _, _, execErr := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_env_params":{}}`, false, false, defaultGasForTests, 0) + require.Empty(t, execErr) + + var resp V010GetEnvResponse + e := json.Unmarshal([]byte(data), &resp) + require.NoError(t, e) + + timeFromContract := convertU64TimeToTimeString(resp.Get.Time) + require.Equal(t, ctx.BlockTime().String(), timeFromContract) + + require.Equal(t, ctx.BlockHeight(), resp.Get.Height) + require.Equal(t, ctx.ChainID(), resp.Get.ChainID) + require.Equal(t, contractAddress.String(), resp.Get.ContractAddress) + require.Equal(t, codeHash, resp.Get.ContractCodeHash) + require.Equal(t, base64.StdEncoding.EncodeToString(keeper.GetContractKey(ctx, contractAddress)), resp.Get.ContractKey) + require.Equal(t, walletA.String(), resp.Get.Sender) + require.Equal(t, coins, resp.Get.SentFunds) +} + +func convertU64TimeToTimeString(timeFromContract uint64) string { + return time.Unix(int64(timeFromContract), 0).String() +} + +func verifyGetEnvFromContract(t *testing.T, ctx sdk.Context, resp v1GetEnvResponse, contractAddress sdk.AccAddress, codeHash string) { + require.Equal(t, ctx.BlockHeight(), resp.Get.Height) + require.Equal(t, ctx.ChainID(), resp.Get.ChainID) + require.Equal(t, contractAddress.String(), resp.Get.ContractAddress) + require.Equal(t, codeHash, resp.Get.ContractCodeHash) + + timeFromContract := convertU64TimeToTimeString(resp.Get.Time) + require.Equal(t, ctx.BlockTime().String(), timeFromContract) +} + +func TestV1EnvParamsFromQuery(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/v1-sanity-contract/v1-contract.wasm", sdk.NewCoins()) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":0}}`, true, true, defaultGasForTests) + + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 10) + queryRes, qErr := queryHelper(t, keeper, ctx, contractAddress, `{"get_env_params":{}}`, true, true, math.MaxUint64) + require.Empty(t, qErr) + + var resp v1GetEnvResponse + e := json.Unmarshal([]byte(queryRes), &resp) + require.NoError(t, e) + + verifyGetEnvFromContract(t, ctx, resp, contractAddress, codeHash) +} + +func TestV1EnvParamsFromExec(t *testing.T) { + ctx, keeper, codeID, codeHash, walletA, privKeyA, _, _ := setupTest(t, "./testdata/v1-sanity-contract/v1-contract.wasm", sdk.NewCoins()) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":0}}`, true, true, defaultGasForTests) + + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 10) + _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_env_params":{}}`, true, true, math.MaxUint64, 0) + require.Empty(t, err) + + var resp v1GetEnvResponse + e := json.Unmarshal([]byte(data), &resp) + require.NoError(t, e) + + verifyGetEnvFromContract(t, ctx, resp, contractAddress, codeHash) +} + +func TestV1MessageInfoFromExec(t *testing.T) { + coins := sdk.NewCoins() + ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/v1-sanity-contract/v1-contract.wasm", coins) + _, _, contractAddress, _, _ := initHelper(t, keeper, ctx, codeID, walletA, privKeyA, `{"counter":{"counter":10, "expires":0}}`, true, true, defaultGasForTests) + + _, _, data, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"get_msg_info":{}}`, true, true, math.MaxUint64, 0) + require.Empty(t, err) + + var resp V1MessageInfoResponse + e := json.Unmarshal([]byte(data), &resp) + require.NoError(t, e) + require.Equal(t, walletA.String(), resp.Get.Sender) + require.Equal(t, coins, resp.Get.Funds) +} + func TestV1ReplySanity(t *testing.T) { ctx, keeper, codeID, _, walletA, privKeyA, _, _ := setupTest(t, "./testdata/v1-sanity-contract/v1-contract.wasm", sdk.NewCoins()) diff --git a/x/compute/internal/keeper/testdata/test-contract/src/contract.rs b/x/compute/internal/keeper/testdata/test-contract/src/contract.rs index 9397aae58..2073ee258 100644 --- a/x/compute/internal/keeper/testdata/test-contract/src/contract.rs +++ b/x/compute/internal/keeper/testdata/test-contract/src/contract.rs @@ -318,6 +318,7 @@ pub enum HandleMsg { }, CosmosMsgCustom {}, InitNewContract {}, + GetEnvParams {}, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -362,6 +363,21 @@ pub enum QueryRes { Get { count: u64 }, } +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum HandleRes { + GetEnvParams { + height: u64, + time: u64, + chain_id: String, + sender: HumanAddr, + sent_funds: Vec, + contract_address: HumanAddr, + contract_key: Option, + contract_code_hash: String, + }, +} + /////////////////////////////// Init /////////////////////////////// pub fn init( @@ -546,7 +562,11 @@ pub fn init( messages: vec![CosmosMsg::Custom(Empty {})], log: vec![], }), - InitMsg::SendMultipleFundsToExecCallback { coins, to, code_hash } => Ok(InitResponse { + InitMsg::SendMultipleFundsToExecCallback { + coins, + to, + code_hash, + } => Ok(InitResponse { messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: to, msg: Binary::from("{\"no_data\":{}}".as_bytes().to_vec()), @@ -555,16 +575,20 @@ pub fn init( })], log: vec![], }), - InitMsg::SendMultipleFundsToInitCallback { coins, code_id, code_hash } => Ok(InitResponse { + InitMsg::SendMultipleFundsToInitCallback { + coins, + code_id, + code_hash, + } => Ok(InitResponse { messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { code_id, msg: Binary::from("{\"nop\":{}}".as_bytes().to_vec()), callback_code_hash: code_hash, send: coins, - label: "test".to_string() + label: "test".to_string(), })], log: vec![], - }) + }), } } @@ -1243,7 +1267,11 @@ pub fn handle( log: vec![], data: None, }), - HandleMsg::SendMultipleFundsToExecCallback { coins, to, code_hash } => Ok(HandleResponse { + HandleMsg::SendMultipleFundsToExecCallback { + coins, + to, + code_hash, + } => Ok(HandleResponse { messages: vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: to, msg: Binary::from("{\"no_data\":{}}".as_bytes().to_vec()), @@ -1253,17 +1281,39 @@ pub fn handle( log: vec![], data: None, }), - HandleMsg::SendMultipleFundsToInitCallback { coins, code_id, code_hash } => Ok(HandleResponse { + HandleMsg::SendMultipleFundsToInitCallback { + coins, + code_id, + code_hash, + } => Ok(HandleResponse { messages: vec![CosmosMsg::Wasm(WasmMsg::Instantiate { code_id, msg: Binary::from("{\"nop\":{}}".as_bytes().to_vec()), callback_code_hash: code_hash, send: coins, - label: "test".to_string() + label: "test".to_string(), })], log: vec![], data: None, - }) + }), + HandleMsg::GetEnvParams {} => Ok(HandleResponse { + messages: vec![], + log: vec![], + data: Some( + to_binary(&HandleRes::GetEnvParams { + height: env.block.height, + time: env.block.time, + chain_id: env.block.chain_id, + sender: env.message.sender, + sent_funds: env.message.sent_funds, + contract_address: env.contract.address, + contract_key: env.contract_key, + contract_code_hash: env.contract_code_hash, + }) + .unwrap(), + ), + // data: Some(to_binary(&env.message.sent_funds).unwrap()),, + }), } } diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs index c6b5b6af9..7d390b5b2 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/contract.rs @@ -669,6 +669,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S resp.data = Some((count as u32).to_be_bytes().into()); return Ok(resp); } + _ => Ok(Response::default()), } } @@ -1164,6 +1165,16 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S funds: coins, })), ), + ExecuteMsg::GetMsgInfo {} => Ok(Response::new().set_data( + to_binary(&QueryRes::GetMsgInfo { + sender: info.sender, + funds: info.funds, + }) + .unwrap(), + )), + ExecuteMsg::GetEnvParams {} => { + Ok(Response::new().set_data(to_binary(&get_env_params(env)?).unwrap())) + } } } @@ -1685,6 +1696,7 @@ pub fn init_new_contract_with_error(env: Env, _deps: DepsMut) -> StdResult StdResult { match msg { QueryMsg::Get {} => to_binary(&get(deps, env)?), + QueryMsg::GetEnvParams {} => to_binary(&get_env_params(env)?), // These were ported from the v0.10 test-contract: QueryMsg::ContractError { error_type } => Err(map_string_to_error(error_type)), @@ -1800,6 +1812,7 @@ pub fn reply(deps: DepsMut, env: Env, reply: Reply) -> StdResult { resp.data = Some((count as u32).to_be_bytes().into()); return Ok(resp); } + _ => Ok(Response::default()), } } None => Err(StdError::generic_err(format!( @@ -2025,6 +2038,16 @@ fn get(deps: Deps, env: Env) -> StdResult { Ok(QueryRes::Get { count }) } +fn get_env_params(env: Env) -> StdResult { + Ok(QueryRes::GetEnvParams { + height: env.block.height, + time: env.block.time.seconds(), + chain_id: env.block.chain_id, + contract_address: env.contract.address, + code_hash: env.contract.code_hash, + }) +} + fn map_string_to_error(error_type: String) -> StdError { let as_str: &str = &error_type[..]; match as_str { diff --git a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs index ff1480e28..ec32da8de 100644 --- a/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs +++ b/x/compute/internal/keeper/testdata/v1-sanity-contract/src/msg.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{Binary, Coin}; +use cosmwasm_std::{Addr, Binary, Coin, Timestamp}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -394,12 +394,15 @@ pub enum ExecuteMsg { amount: Vec, }, CosmosMsgCustom {}, + GetMsgInfo {}, + GetEnvParams {}, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { Get {}, + GetEnvParams {}, // These were ported from the v0.10 test-contract: ContractError { error_type: String, @@ -438,7 +441,20 @@ pub enum QueryMsg { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryRes { - Get { count: u64 }, + Get { + count: u64, + }, + GetEnvParams { + height: u64, + time: u64, + chain_id: String, + contract_address: Addr, + code_hash: String, + }, + GetMsgInfo { + sender: Addr, + funds: Vec, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]