use ibc_core_client::context::ClientValidationContext;
use ibc_core_client::types::Height;
use ibc_core_connection_types::error::ConnectionError;
use ibc_core_connection_types::ConnectionEnd;
use ibc_core_handler_types::error::ContextError;
use ibc_core_host::ValidationContext;
pub fn verify_conn_delay_passed<Ctx>(
ctx: &Ctx,
packet_proof_height: Height,
connection_end: &ConnectionEnd,
) -> Result<(), ContextError>
where
Ctx: ValidationContext,
{
let current_host_time = ctx.host_timestamp()?;
let current_host_height = ctx.host_height()?;
let client_id = connection_end.client_id();
let last_client_update_time = ctx
.get_client_validation_context()
.client_update_time(client_id, &packet_proof_height)?;
let last_client_update_height = ctx
.get_client_validation_context()
.client_update_height(client_id, &packet_proof_height)?;
let conn_delay_time_period = connection_end.delay_period();
let conn_delay_height_period = ctx.block_delay(&conn_delay_time_period);
let earliest_valid_time = (last_client_update_time + conn_delay_time_period)
.map_err(ConnectionError::TimestampOverflow)?;
if current_host_time < earliest_valid_time {
return Err(ContextError::ConnectionError(
ConnectionError::NotEnoughTimeElapsed {
current_host_time,
earliest_valid_time,
},
));
}
let earliest_valid_height = last_client_update_height.add(conn_delay_height_period);
if current_host_height < earliest_valid_height {
return Err(ContextError::ConnectionError(
ConnectionError::NotEnoughBlocksElapsed {
current_host_height,
earliest_valid_height,
},
));
};
Ok(())
}