Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions light-clients/ics10-grandpa-cw/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ hyperspace-primitives = { path = "../../hyperspace/primitives", features = ["tes
pallet-ibc = { path = "../../contracts/pallet-ibc" }
serde-json-wasm = { version = "0.5.0", default-features = false }
serde_json = { version = "1.0.93", default-features = false }
tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false }


[features]
# for more explicit tests, cargo test --features=backtraces
Expand Down
75 changes: 72 additions & 3 deletions light-clients/ics10-grandpa-cw/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use byteorder::{ByteOrder, LittleEndian};
use core::hash::Hasher;
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult};
use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, StdError};
use cw_storage_plus::{Item, Map};
use digest::Digest;
use grandpa_light_client_primitives::justification::AncestryChain;
Expand Down Expand Up @@ -333,7 +333,7 @@ fn process_message(
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
let client_id = ClientId::from_str("08-wasm-0").expect("client id is valid");
match msg {
QueryMsg::ClientTypeMsg(_) => unimplemented!("ClientTypeMsg"),
Expand All @@ -351,7 +351,13 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
} else {
let height = client_state.latest_height();
match get_consensus_state(deps, &client_id, height) {
Ok(_) => to_binary(&QueryResponse::status("Active".to_string())),
Ok(consensus_state_raw) => {
let consensus_state = Context::<HostFunctions>::decode_consensus_state(&consensus_state_raw).map_err(|e|StdError::serialize_err(e.to_string(), e.to_string()))?;
if client_state.expired(core::time::Duration::from_secs(env.block.time.seconds() - consensus_state.timestamp.unix_timestamp() as u64)) {
return to_binary(&QueryResponse::status("Expired".to_string()));
}
to_binary(&QueryResponse::status("Active".to_string()))
},
Err(_) => to_binary(&QueryResponse::status("Expired".to_string())),
}
}
Expand Down Expand Up @@ -433,3 +439,66 @@ pub extern "C" fn ext_hashing_twox_64_version_1(data: i64) -> i32 {
let out_ptr = Box::leak(hash).as_ptr();
out_ptr as i32
}


#[cfg(test)]
mod tests {
use cosmwasm_std::from_binary;
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
use tendermint::Time;
use ibc::core::ics02_client::client_state::ClientState as _;

use crate::ics23::ClientStates;

use super::*;
#[test]
fn test_query() {

let mut deps = mock_dependencies();
let env = mock_env();


for (expected, offset) in [("Active", 0i64), ("Expired", env.block.time.seconds() as i64 - 10), ("Frozen", 0i64)] {
let mut client_state = ics10_grandpa::client_state::ClientState::<HostFunctions>::default();
let mut consensus_state = ics10_grandpa::consensus_state::ConsensusState::new(vec![], Time::from_unix_timestamp(0, 0).unwrap());
let height = Height { revision_number: 0, revision_height: 1000};
client_state.latest_para_height = height.revision_height as _;


consensus_state.timestamp = Time::from_unix_timestamp(env.block.time.seconds() as i64 - offset, 0).unwrap();
let deps_mut = deps.as_mut();
let mut client_states = ClientStates::new(deps_mut.storage);
if expected == "Frozen" {
let height = Height { revision_number: 0, revision_height: height.revision_height - 100};
client_state = client_state.with_frozen_height(height.clone()).unwrap();
}

client_states.insert(client_state.encode_to_vec().unwrap());

let mut context = Context::new(deps_mut, env.clone());
context.store_client_state(ClientId::default(), client_state).unwrap();
context.store_consensus_state(ClientId::default(), height , consensus_state).unwrap();

let resp = query(
deps.as_ref(),
mock_env(),
QueryMsg::Status(StatusMsg{})
).unwrap();

instantiate(
deps.as_mut(),
env.clone(),
mock_info("sender", &[]),
InstantiateMsg { } ,
)
.unwrap();

let resp: QueryResponse = from_binary(&resp).unwrap();

assert_eq!(
resp,
QueryResponse::status(expected.to_string())
);
}
}
}