diff --git a/solana/solana-ibc/programs/solana-ibc/Cargo.toml b/solana/solana-ibc/programs/solana-ibc/Cargo.toml index d9c228c6..63771bae 100644 --- a/solana/solana-ibc/programs/solana-ibc/Cargo.toml +++ b/solana/solana-ibc/programs/solana-ibc/Cargo.toml @@ -17,6 +17,7 @@ mocks = ["ibc-testkit"] no-entrypoint = [] no-idl = [] no-log-ix-name = [] +witness = [] [dependencies] anchor-lang.workspace = true diff --git a/solana/solana-ibc/programs/solana-ibc/src/validation_context.rs b/solana/solana-ibc/programs/solana-ibc/src/validation_context.rs index 7c0624d4..53b1f9a0 100644 --- a/solana/solana-ibc/programs/solana-ibc/src/validation_context.rs +++ b/solana/solana-ibc/programs/solana-ibc/src/validation_context.rs @@ -1,15 +1,15 @@ use std::str::FromStr; use std::time::Duration; -use anchor_lang::prelude::Pubkey; +use anchor_lang::prelude::{Pubkey, SolanaSysvar}; use lib::hash::CryptoHash; +use spl_token::solana_program::clock::Clock; use crate::client_state::AnyClientState; use crate::consensus_state::AnyConsensusState; use crate::ibc::{self, ConsensusState}; use crate::storage::{self, IbcStorage}; - type Result = core::result::Result; impl ibc::ValidationContext for IbcStorage<'_, '_> { @@ -22,7 +22,12 @@ impl ibc::ValidationContext for IbcStorage<'_, '_> { &self, client_id: &ibc::ClientId, ) -> Result { - Ok(self.borrow().private.client(client_id)?.client_state.get()?) + self.borrow() + .private + .client(client_id)? + .client_state + .get() + .map_err(Into::into) } fn decode_client_state( @@ -43,13 +48,27 @@ impl ibc::ValidationContext for IbcStorage<'_, '_> { } fn host_height(&self) -> Result { - let height = u64::from(self.borrow().chain.head()?.block_height); - let height = ibc::Height::new(1, height)?; - Ok(height) + let height = if cfg!(feature = "witness") { + Clock::get() + .map_err(|e| ibc::ClientError::ClientSpecific { + description: e.to_string(), + })? + .slot + } else { + u64::from(self.borrow().chain.head()?.block_height) + }; + Ok(ibc::Height::new(1, height)?) } fn host_timestamp(&self) -> Result { - let timestamp = self.borrow().chain.head()?.timestamp_ns.get(); + let timestamp = if cfg!(feature = "witness") { + let clock = Clock::get().map_err(|e| { + ibc::ClientError::ClientSpecific { description: e.to_string() } + })?; + clock.unix_timestamp as u64 * 10u64.pow(9) + } else { + self.borrow().chain.head()?.timestamp_ns.get() + }; ibc::Timestamp::from_nanoseconds(timestamp).map_err(|err| { ibc::ClientError::Other { description: err.to_string() }.into() }) @@ -296,7 +315,6 @@ impl IbcStorage<'_, '_> { } } - impl ibc::ClientValidationContext for IbcStorage<'_, '_> { fn update_meta( &self,