Skip to content

Commit

Permalink
added mock client and consensus state (#27)
Browse files Browse the repository at this point in the history
* added mock client and consensus state

* added tendermint patch and updated program id

* fix code format

* fix issues in contract

* cargo +nightly fmt

* fix formatting

* reduce diff noise

* storing height while storing consensus state and returning current timestamp when host_timestamp is called

* rm channel counter update

* remove local ibc crate

* added mocks feature

* fix formatting

* reduce diff noise

---------

Co-authored-by: Michal Nazarewicz <[email protected]>
  • Loading branch information
dhruvja and mina86 authored Oct 13, 2023
1 parent 820b0d7 commit 13ac224
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 28 deletions.
9 changes: 5 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
*.rs.bk
.DS_Store
.anchor
Cargo.lock
/dist/
.DS_Store
*.rs.bk
Cargo.lock
local-ibc
node_modules
package-lock.json
target
test-ledger
test-ledger
4 changes: 2 additions & 2 deletions Anchor.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
seeds = false
skip-lint = false
[programs.localnet]
solana_ibc = "7MEuaEwNMsjVCJy9N31ZgvQf1dFkRNXYFREaAjMsoE5g"
solana_ibc = "EnfDJsAK7BGgetnmKzBx86CsgC5kfSPcsktFCQ4YLC81"
[programs.devnet]
solana_ibc = "7MEuaEwNMsjVCJy9N31ZgvQf1dFkRNXYFREaAjMsoE5g"
solana_ibc = "EnfDJsAK7BGgetnmKzBx86CsgC5kfSPcsktFCQ4YLC81"

[registry]
url = "https://api.apr.dev"
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ base64 = { version = "0.21", default-features = false, features = ["alloc"] }
bincode = "1.3.3"
borsh = { version = "0.10.3", default-features = false }
derive_more = "0.99.17"
ibc = { version = "0.45.0", default-features = false, features = ["serde"] }
ibc = { version = "0.45.0", default-features = false, features = ["serde", "mocks", "std"] }
ibc-proto = { version = "0.35.0", default-features = false, features = ["serde"] }
pretty_assertions = "1.4.0"
rand = { version = "0.8.5" }
Expand Down
1 change: 1 addition & 0 deletions solana/solana-ibc/programs/solana-ibc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ no-entrypoint = []
no-idl = []
no-log-ix-name = []
cpi = ["no-entrypoint"]
mocks = []

[dependencies]
anchor-lang.workspace = true
Expand Down
129 changes: 127 additions & 2 deletions solana/solana-ibc/programs/solana-ibc/src/client_state.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anchor_lang::solana_program::msg;
use ibc::clients::ics07_tendermint::client_state::ClientState as TmClientState;
use ibc::core::ics02_client::client_state::{
ClientStateCommon, ClientStateExecution, ClientStateValidation, UpdateKind,
Expand All @@ -11,8 +12,14 @@ use ibc::core::ics24_host::identifier::ClientId;
use ibc::core::ics24_host::path::{ClientConsensusStatePath, Path};
use ibc::core::timestamp::Timestamp;
use ibc::core::{ContextError, ValidationContext};
#[cfg(any(test, feature = "mocks"))]
use ibc::mock::client_state::{
MockClientContext, MockClientState, MOCK_CLIENT_STATE_TYPE_URL,
};
use ibc::{Any, Height};
use ibc_proto::ibc::lightclients::tendermint::v1::ClientState as RawTmClientState;
#[cfg(any(test, feature = "mocks"))]
use ibc_proto::ibc::mock::ClientState as RawMockClientState;
use ibc_proto::protobuf::Protobuf;
use serde::{Deserialize, Serialize};

Expand All @@ -25,6 +32,8 @@ const TENDERMINT_CLIENT_STATE_TYPE_URL: &str =
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub enum AnyClientState {
Tendermint(TmClientState),
#[cfg(any(test, feature = "mocks"))]
Mock(MockClientState),
}

impl Protobuf<Any> for AnyClientState {}
Expand All @@ -41,6 +50,13 @@ impl TryFrom<Any> for AnyClientState {
},
)?,
)),
#[cfg(any(test, feature = "mocks"))]
MOCK_CLIENT_STATE_TYPE_URL => Ok(AnyClientState::Mock(
Protobuf::<RawMockClientState>::decode_vec(&raw.value)
.map_err(|e| ClientError::ClientSpecific {
description: e.to_string(),
})?,
)),
_ => Err(ClientError::UnknownClientStateType {
client_state_type: raw.type_url,
}),
Expand All @@ -55,6 +71,13 @@ impl From<AnyClientState> for Any {
type_url: TENDERMINT_CLIENT_STATE_TYPE_URL.to_string(),
value: Protobuf::<RawTmClientState>::encode_vec(&client_state),
},
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(mock_client_state) => Any {
type_url: MOCK_CLIENT_STATE_TYPE_URL.to_string(),
value: Protobuf::<RawMockClientState>::encode_vec(
&mock_client_state,
),
},
}
}
}
Expand All @@ -75,6 +98,14 @@ impl ClientStateValidation<SolanaIbcStorage> for AnyClientState {
client_message,
update_kind,
),
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(mock_client_state) => mock_client_state
.verify_client_message(
ctx,
client_id,
client_message,
update_kind,
),
}
}

Expand All @@ -93,6 +124,14 @@ impl ClientStateValidation<SolanaIbcStorage> for AnyClientState {
client_message,
update_kind,
),
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(mock_client_state) => mock_client_state
.check_for_misbehaviour(
ctx,
client_id,
client_message,
update_kind,
),
}
}

Expand All @@ -115,6 +154,10 @@ impl ClientStateCommon for AnyClientState {
AnyClientState::Tendermint(client_state) => {
client_state.verify_consensus_state(consensus_state)
}
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(mock_client_state) => {
mock_client_state.verify_consensus_state(consensus_state)
}
}
}

Expand All @@ -123,15 +166,30 @@ impl ClientStateCommon for AnyClientState {
AnyClientState::Tendermint(client_state) => {
client_state.client_type()
}
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(mock_client_state) => {
mock_client_state.client_type()
}
}
}

fn latest_height(&self) -> Height {
match self {
msg!("Fetching the height");
let height = match self {
AnyClientState::Tendermint(client_state) => {
client_state.latest_height()
}
}
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(mock_client_state) => {
msg!(
"This is latest height {:?}",
mock_client_state.latest_height()
);
mock_client_state.latest_height()
}
};
msg!("This was the height {}", height);
height
}

fn validate_proof_height(
Expand All @@ -142,6 +200,10 @@ impl ClientStateCommon for AnyClientState {
AnyClientState::Tendermint(client_state) => {
client_state.validate_proof_height(proof_height)
}
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(client_state) => {
client_state.validate_proof_height(proof_height)
}
}
}

Expand All @@ -162,6 +224,15 @@ impl ClientStateCommon for AnyClientState {
proof_upgrade_consensus_state,
root,
),
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(client_state) => client_state
.verify_upgrade_client(
upgraded_client_state,
upgraded_consensus_state,
proof_upgrade_client,
proof_upgrade_consensus_state,
root,
),
}
}

Expand All @@ -177,6 +248,10 @@ impl ClientStateCommon for AnyClientState {
AnyClientState::Tendermint(client_state) => {
client_state.verify_membership(prefix, proof, root, path, value)
}
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(client_state) => {
client_state.verify_membership(prefix, proof, root, path, value)
}
}
}

Expand All @@ -191,6 +266,10 @@ impl ClientStateCommon for AnyClientState {
AnyClientState::Tendermint(client_state) => {
client_state.verify_non_membership(prefix, proof, root, path)
}
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(client_state) => {
client_state.verify_non_membership(prefix, proof, root, path)
}
}
}
}
Expand All @@ -199,6 +278,11 @@ impl From<TmClientState> for AnyClientState {
fn from(value: TmClientState) -> Self { AnyClientState::Tendermint(value) }
}

#[cfg(any(test, feature = "mocks"))]
impl From<MockClientState> for AnyClientState {
fn from(value: MockClientState) -> Self { AnyClientState::Mock(value) }
}

impl ClientStateExecution<SolanaIbcStorage> for AnyClientState {
fn initialise(
&self,
Expand All @@ -210,6 +294,10 @@ impl ClientStateExecution<SolanaIbcStorage> for AnyClientState {
AnyClientState::Tendermint(client_state) => {
client_state.initialise(ctx, client_id, consensus_state)
}
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(client_state) => {
client_state.initialise(ctx, client_id, consensus_state)
}
}
}

Expand All @@ -223,6 +311,10 @@ impl ClientStateExecution<SolanaIbcStorage> for AnyClientState {
AnyClientState::Tendermint(client_state) => {
client_state.update_state(ctx, client_id, header)
}
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(client_state) => {
client_state.update_state(ctx, client_id, header)
}
}
}

Expand All @@ -241,6 +333,14 @@ impl ClientStateExecution<SolanaIbcStorage> for AnyClientState {
client_message,
update_kind,
),
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(client_state) => client_state
.update_state_on_misbehaviour(
ctx,
client_id,
client_message,
update_kind,
),
}
}

Expand All @@ -259,6 +359,14 @@ impl ClientStateExecution<SolanaIbcStorage> for AnyClientState {
upgraded_client_state,
upgraded_consensus_state,
),
#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(client_state) => client_state
.update_state_on_upgrade(
ctx,
client_id,
upgraded_client_state,
upgraded_consensus_state,
),
}
}
}
Expand All @@ -276,6 +384,23 @@ impl ibc::clients::ics07_tendermint::CommonContext for SolanaIbcStorage {
}
}

#[cfg(any(test, feature = "mocks"))]
impl MockClientContext for SolanaIbcStorage {
type ConversionError = ClientError;
type AnyConsensusState = AnyConsensusState;

fn consensus_state(
&self,
client_cons_state_path: &ClientConsensusStatePath,
) -> Result<Self::AnyConsensusState, ContextError> {
ValidationContext::consensus_state(self, client_cons_state_path)
}

fn host_timestamp(&self) -> Result<Timestamp, ContextError> {
ValidationContext::host_timestamp(self)
}
}

impl ibc::clients::ics07_tendermint::ValidationContext for SolanaIbcStorage {
fn host_timestamp(&self) -> Result<Timestamp, ContextError> {
ValidationContext::host_timestamp(self)
Expand Down
Loading

0 comments on commit 13ac224

Please sign in to comment.