Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Client queries after last protobuf updates #309

Merged
merged 5 commits into from
Oct 15, 2020
Merged
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
76 changes: 43 additions & 33 deletions modules/src/ics02_client/client_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ use crate::Height;

use tendermint_proto::{DomainType, Error, Kind};

pub const TENDERMINT_CLIENT_STATE_TYPE_URL: &str = "/ibc.lightclients.tendermint.v1.ClientState";
pub const TENDERMINT_CONSENSUS_STATE_TYPE_URL: &str =
"/ibc.lightclients.tendermint.v1.ConsensusState";
pub const MOCK_CLIENT_STATE_TYPE_URL: &str = "/ibc.mock.ClientState";
pub const MOCK_CONSENSUS_STATE_TYPE_URL: &str = "/ibc.mock.ConsensusState";
ancazamfir marked this conversation as resolved.
Show resolved Hide resolved

#[cfg(test)]
use {
crate::mock_client::client_def::MockClient,
Expand Down Expand Up @@ -119,12 +125,20 @@ pub enum AnyClientState {
}

impl AnyClientState {
pub fn height(&self) -> Height {
pub fn latest_height(&self) -> Height {
match self {
AnyClientState::Tendermint(tcs) => tcs.latest_height(),
Self::Tendermint(tm_state) => tm_state.latest_height(),

#[cfg(test)]
AnyClientState::Mock(mcs) => mcs.latest_height(),
Self::Mock(mock_state) => mock_state.latest_height(),
}
}
pub fn client_type(&self) -> ClientType {
match self {
Self::Tendermint(state) => state.client_type(),

#[cfg(test)]
Self::Mock(state) => state.client_type(),
}
}
}
Expand All @@ -137,12 +151,12 @@ impl TryFrom<Any> for AnyClientState {
// TODO Fix type urls: avoid having hardcoded values sprinkled around the whole codebase.
fn try_from(raw: Any) -> Result<Self, Self::Error> {
match raw.type_url.as_str() {
"/ibc.tendermint.ClientState" => Ok(AnyClientState::Tendermint(
TENDERMINT_CLIENT_STATE_TYPE_URL => Ok(AnyClientState::Tendermint(
TendermintClientState::decode_vec(&raw.value)?,
)),

#[cfg(test)]
"/ibc.mock.ClientState" => Ok(AnyClientState::Mock(MockClientState::decode_vec(
MOCK_CLIENT_STATE_TYPE_URL => Ok(AnyClientState::Mock(MockClientState::decode_vec(
&raw.value,
)?)),

Expand All @@ -157,12 +171,12 @@ impl From<AnyClientState> for Any {
fn from(value: AnyClientState) -> Self {
match value {
AnyClientState::Tendermint(value) => Any {
type_url: "/ibc.tendermint.ClientState".to_string(),
type_url: TENDERMINT_CLIENT_STATE_TYPE_URL.to_string(),
value: value.encode_vec().unwrap(),
},
#[cfg(test)]
AnyClientState::Mock(value) => Any {
type_url: "/ibc.mock.ClientState".to_string(),
type_url: MOCK_CLIENT_STATE_TYPE_URL.to_string(),
value: value.encode_vec().unwrap(),
},
}
Expand All @@ -175,21 +189,11 @@ impl ClientState for AnyClientState {
}

fn client_type(&self) -> ClientType {
match self {
Self::Tendermint(state) => state.client_type(),

#[cfg(test)]
Self::Mock(state) => state.client_type(),
}
self.client_type()
}

fn latest_height(&self) -> Height {
match self {
Self::Tendermint(tm_state) => tm_state.latest_height(),

#[cfg(test)]
Self::Mock(mock_state) => mock_state.latest_height(),
}
self.latest_height()
}

fn is_frozen(&self) -> bool {
Expand All @@ -210,27 +214,33 @@ pub enum AnyConsensusState {
Mock(MockConsensusState),
}

impl AnyConsensusState {
pub fn client_type(&self) -> ClientType {
match self {
AnyConsensusState::Tendermint(_cs) => ClientType::Tendermint,

#[cfg(test)]
AnyConsensusState::Mock(_cs) => ClientType::Mock,
}
}
}

impl DomainType<Any> for AnyConsensusState {}

impl TryFrom<Any> for AnyConsensusState {
type Error = Error;

fn try_from(value: Any) -> Result<Self, Self::Error> {
match value.type_url.as_str() {
"/ibc.tendermint.ConsensusState" => Ok(AnyConsensusState::Tendermint(
TENDERMINT_CONSENSUS_STATE_TYPE_URL => Ok(AnyConsensusState::Tendermint(
TendermintConsensusState::decode_vec(&value.value)?,
)),

// TODO get this to compile! -- Add the ClientConsensusState definition in ibc-proto.
// #[cfg(test)]
// "/ibc.mock.ConsensusState" => {
// let raw = RawMockConsensusState::decode(value.value.as_ref())
// .map_err(|e| error::Kind::ProtoDecodingFailure.context(e))?;
// let client_state = MockClientState::try_from(raw)
// .map_err(|e| error::Kind::InvalidRawClientState.context(e))?;
//
// Ok(AnyClientState::Mock(client_state))
// }
#[cfg(test)]
MOCK_CONSENSUS_STATE_TYPE_URL => Ok(AnyConsensusState::Mock(
MockConsensusState::decode_vec(&value.value)?,
)),

_ => Err(Kind::DecodeMessage
.context(error::Kind::UnknownConsensusStateType(value.type_url))
.into()),
Expand All @@ -242,12 +252,12 @@ impl From<AnyConsensusState> for Any {
fn from(value: AnyConsensusState) -> Self {
match value {
AnyConsensusState::Tendermint(value) => Any {
type_url: "/ibc.tendermint.ConsensusState".to_string(),
type_url: TENDERMINT_CONSENSUS_STATE_TYPE_URL.to_string(),
value: value.encode_vec().unwrap(),
},
#[cfg(test)]
AnyConsensusState::Mock(value) => Any {
type_url: "/ibc.mock.ConsensusState".to_string(),
type_url: MOCK_CONSENSUS_STATE_TYPE_URL.to_string(),
value: value.encode_vec().unwrap(),
},
}
Expand All @@ -256,7 +266,7 @@ impl From<AnyConsensusState> for Any {

impl ConsensusState for AnyConsensusState {
fn client_type(&self) -> ClientType {
todo!()
self.client_type()
romac marked this conversation as resolved.
Show resolved Hide resolved
}

fn root(&self) -> &CommitmentRoot {
Expand Down
17 changes: 8 additions & 9 deletions modules/src/ics02_client/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,34 @@ pub trait ClientReader {

/// Defines the write-only part of ICS2 (client functions) context.
pub trait ClientKeeper {
fn store_client_type(
&mut self,
client_id: ClientId,
client_type: ClientType,
) -> Result<(), Error>;

fn store_client_result(&mut self, handler_res: ClientResult) -> Result<(), Error> {
match handler_res {
CreateResult(res) => {
self.store_client_type(res.client_id.clone(), res.client_type)?;
ancazamfir marked this conversation as resolved.
Show resolved Hide resolved
self.store_client_state(res.client_id.clone(), res.client_state.clone())?;
self.store_consensus_state(
res.client_id,
res.client_state.height(),
res.client_state.latest_height(),
res.consensus_state,
)?;
}
UpdateResult(res) => {
self.store_client_state(res.client_id.clone(), res.client_state.clone())?;
self.store_consensus_state(
res.client_id,
res.client_state.height(),
res.client_state.latest_height(),
res.consensus_state,
)?;
}
}
Ok(())
}

fn store_client_type(
&mut self,
client_id: ClientId,
client_type: ClientType,
) -> Result<(), Error>;

fn store_client_state(
&mut self,
client_id: ClientId,
Expand Down
46 changes: 18 additions & 28 deletions modules/src/ics02_client/context_mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::ics02_client::client_def::{AnyClientState, AnyConsensusState};
use crate::ics02_client::client_type::ClientType;
use crate::ics02_client::context::{ClientKeeper, ClientReader};
use crate::ics02_client::error::{Error, Kind};
use crate::ics02_client::state::ClientState;
use crate::ics24_host::identifier::ClientId;
use crate::mock_client::header::MockHeader;
use crate::mock_client::state::{MockClientRecord, MockClientState, MockConsensusState};
Expand Down Expand Up @@ -51,38 +52,27 @@ impl MockClientContext {
/// context. The client will have mock client state and a mock consensus state for the given
/// height.
pub fn with_client(&mut self, client_id: &ClientId, client_type: ClientType, h: Height) {
let mut client_record = MockClientRecord {
client_type,
client_state: MockClientState(MockHeader(h)),
consensus_states: HashMap::with_capacity(1),
};
client_record
.consensus_states
.insert(h, MockConsensusState(MockHeader(h)));
self.clients.insert(client_id.clone(), client_record);
}

/// Given a client type, an id, and a height, this function registers in the context a new
/// client record for that type and id. This client record will have no consensus states, and a
/// default client state for the input height.
pub fn with_client_type(&mut self, client_id: &ClientId, client_type: ClientType, h: Height) {
let client_record = MockClientRecord {
client_type,
client_state: MockClientState(MockHeader(h)),
consensus_states: Default::default(),
};
self.clients.insert(client_id.clone(), client_record);
match client_type {
ClientType::Mock => {
let mut client_record = MockClientRecord {
client_type: ClientType::Mock,
client_state: MockClientState(MockHeader(h)),
consensus_states: HashMap::with_capacity(1),
};
client_record
.consensus_states
.insert(h, MockConsensusState(MockHeader(h)));
self.clients.insert(client_id.clone(), client_record);
}
_ => unimplemented!(),
}
}

/// Given a client id and a height, registers a new client in the context and also associates
/// to this client a mock client state and a mock consensus state for the input height. The type
/// of this client is implicitly assumed to be Mock.
pub fn with_client_consensus_state(&mut self, client_id: &ClientId, h: Height) {
let mut client_record = MockClientRecord {
client_type: ClientType::Mock,
client_state: MockClientState(MockHeader(h)),
consensus_states: HashMap::with_capacity(1),
};
let mut client_record = self.clients.get(client_id).unwrap().clone();
client_record
.consensus_states
.insert(h, MockConsensusState(MockHeader(h)));
Expand All @@ -93,7 +83,7 @@ impl MockClientContext {
impl ClientReader for MockClientContext {
fn client_type(&self, client_id: &ClientId) -> Option<ClientType> {
match self.clients.get(client_id) {
Some(client_record) => client_record.client_type.into(),
Some(client_record) => client_record.client_state.client_type().into(),
None => None,
}
}
Expand Down Expand Up @@ -161,8 +151,8 @@ impl ClientKeeper for MockClientContext {
match consensus_state {
AnyConsensusState::Mock(consensus_state) => {
let client_record = self.clients.entry(client_id).or_insert(MockClientRecord {
client_type: ClientType::Mock,
consensus_states: Default::default(),
client_type: ClientType::Mock,
client_state: Default::default(),
});
client_record
Expand Down
6 changes: 6 additions & 0 deletions modules/src/ics02_client/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ pub enum Kind {
#[error("invalid raw client consensus state")]
InvalidRawConsensusState,

#[error("mismatch raw client consensus state")]
RawClientAndConsensusStateTypesMismatch {
state_type: ClientType,
consensus_type: ClientType,
},

#[error("invalid raw header")]
InvalidRawHeader,

Expand Down
Loading