Skip to content

Commit

Permalink
Enable tests in the foreign_client module
Browse files Browse the repository at this point in the history
  • Loading branch information
vitorenesduarte committed Jan 21, 2021
1 parent f0227bf commit d60a38f
Show file tree
Hide file tree
Showing 21 changed files with 322 additions and 242 deletions.
68 changes: 56 additions & 12 deletions modules/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use std::collections::HashMap;
use std::convert::{TryFrom, TryInto};
use tendermint::block::Height;

use tendermint::abci::Event;
use tracing::warn;

/// Events types
Expand Down Expand Up @@ -69,26 +68,70 @@ pub enum IBCEvent {
ChainError(String), // Special event, signifying an error on CheckTx or DeliverTx
}

#[derive(Debug)]
pub struct GenericEvent<'a> {
pub type_str: &'a str,
pub attributes: Vec<(&'a str, &'a str)>,
}

impl<'a> GenericEvent<'a> {
fn from_tx_response_event(event: &'a tendermint::abci::Event) -> Self {
let type_str = event.type_str.as_ref();
let attributes = event
.attributes
.iter()
.map(|tag| (tag.key.as_ref(), tag.value.as_ref()))
.collect();
Self {
type_str,
attributes,
}
}

fn from_handler_event(event: &'a crate::handler::Event) -> Self {
let type_str = match &event.event_type {
crate::handler::EventType::Custom(type_str) => type_str.as_ref(),
_ => unimplemented!(),
};
let attributes = event
.attributes
.iter()
.map(|tag| (tag.key().as_ref(), tag.value().as_ref()))
.collect();
Self {
type_str,
attributes,
}
}
}

// This is tendermint specific
pub fn from_tx_response_event(event: Event) -> Option<IBCEvent> {
pub fn from_tx_response_event(event: &tendermint::abci::Event) -> Option<IBCEvent> {
from_generic_event(GenericEvent::from_tx_response_event(event))
}

pub fn from_handler_event(event: &crate::handler::Event) -> Option<IBCEvent> {
from_generic_event(GenericEvent::from_handler_event(event))
}

fn from_generic_event(event: GenericEvent<'_>) -> Option<IBCEvent> {
// Return the first hit we find
// Look for client event...
if let Some(client_res) = ClientEvents::try_from_tx(event.clone()) {
return Some(client_res);
// Look for connection event...
} else if let Some(conn_res) = ConnectionEvents::try_from_tx(event.clone()) {
return Some(conn_res);
} else if let Some(chan_res) = ChannelEvents::try_from_tx(event) {
return Some(chan_res);
if let Some(client_res) = ClientEvents::try_from_event(&event) {
Some(client_res)
} else if let Some(conn_res) = ConnectionEvents::try_from_event(&event) {
Some(conn_res)
} else if let Some(chan_res) = ChannelEvents::try_from_event(&event) {
Some(chan_res)
} else {
None
}

None
}

impl IBCEvent {
pub fn to_json(&self) -> String {
serde_json::to_string(self).unwrap()
}

pub fn height(&self) -> Height {
match self {
IBCEvent::NewBlock(bl) => bl.height,
Expand All @@ -102,6 +145,7 @@ impl IBCEvent {
_ => unimplemented!(),
}
}

pub fn set_height(&mut self, height: ICSHeight) {
match self {
IBCEvent::SendPacketChannel(ev) => {
Expand Down
19 changes: 7 additions & 12 deletions modules/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ impl Attribute {
Self { key, value }
}

pub fn value(&self) -> String {
self.value.clone()
pub fn value(&self) -> &String {
&self.value
}

pub fn key(&self) -> String {
self.key.clone()
pub fn key(&self) -> &String {
&self.key
}
}

Expand All @@ -28,25 +28,20 @@ pub enum EventType {

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Event {
pub tpe: EventType,
pub event_type: EventType,
pub attributes: Vec<Attribute>,
}

impl Event {
pub fn new(tpe: EventType, attrs: Vec<(String, String)>) -> Self {
pub fn new(event_type: EventType, attrs: Vec<(String, String)>) -> Self {
Self {
tpe,
event_type,
attributes: attrs
.into_iter()
.map(|(k, v)| Attribute::new(k, v))
.collect(),
}
}

/// Returns a vector containing the values within all attributes of this event
pub fn attribute_values(&self) -> Vec<String> {
self.attributes.iter().map(|a| a.value.clone()).collect()
}
}

pub type HandlerResult<T, E> = Result<HandlerOutput<T>, E>;
Expand Down
54 changes: 26 additions & 28 deletions modules/src/ics02_client/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use anomaly::BoxError;

use crate::ics02_client::height::Height;
use serde_derive::{Deserialize, Serialize};
use std::collections::HashSet;
use std::convert::{TryFrom, TryInto};
use tendermint::block;

Expand All @@ -16,41 +15,40 @@ pub const CREATE_EVENT_TYPE: &str = "create_client";
pub const UPDATE_EVENT_TYPE: &str = "update_client";

/// The content of the `key` field for the attribute containing the client identifier.
pub const CLIENT_ID_ATTRIBUTE_KEY: &str = "client_id";
const CLIENT_ID_ATTRIBUTE_KEY: &str = "client_id";

/// The content of the `key` field for the attribute containing the client type.
pub const CLIENT_TYPE_ATTRIBUTE_KEY: &str = "client_type";
const CLIENT_TYPE_ATTRIBUTE_KEY: &str = "client_type";

/// The content of the `key` field for the attribute containing the height.
pub const CONSENSUS_HEIGHT_ATTRIBUTE_KEY: &str = "consensus_height";

/// A list of all the event `type`s that this module is capable of parsing
fn event_types() -> HashSet<String> {
vec![CREATE_EVENT_TYPE.to_string(), UPDATE_EVENT_TYPE.to_string()]
.into_iter()
.collect()
const CONSENSUS_HEIGHT_ATTRIBUTE_KEY: &str = "consensus_height";

pub fn try_from_event(event: &crate::events::GenericEvent<'_>) -> Option<IBCEvent> {
match event.type_str {
CREATE_EVENT_TYPE => Some(IBCEvent::CreateClient(CreateClient(
extract_attributes_from_event(event),
))),
UPDATE_EVENT_TYPE => Some(IBCEvent::UpdateClient(UpdateClient(
extract_attributes_from_event(event),
))),
_ => None,
}
}

pub fn try_from_tx(event: tendermint::abci::Event) -> Option<IBCEvent> {
event_types().get(&event.type_str)?;
fn extract_attributes_from_event(event: &crate::events::GenericEvent<'_>) -> Attributes {
let mut attr = Attributes::default();

for tag in event.attributes {
match tag.key.as_ref() {
CLIENT_ID_ATTRIBUTE_KEY => attr.client_id = tag.value.to_string().parse().unwrap(),
CLIENT_TYPE_ATTRIBUTE_KEY => attr.client_type = tag.value.to_string().parse().unwrap(),
CONSENSUS_HEIGHT_ATTRIBUTE_KEY => {
attr.consensus_height = tag.value.to_string().try_into().unwrap()
}
_ => {}
for (key, value) in &event.attributes {
match key.as_ref() {
CLIENT_ID_ATTRIBUTE_KEY => attr.client_id = value.parse().unwrap(),
CLIENT_TYPE_ATTRIBUTE_KEY => attr.client_type = value.parse().unwrap(),
CONSENSUS_HEIGHT_ATTRIBUTE_KEY => attr.consensus_height = value.parse().unwrap(),
// TODO: `Attributes` has 4 fields and we're only parsing 3; is that intended?
_ => panic!("unexpected attribute key: {}", key),
}
}

match event.type_str.as_str() {
CREATE_EVENT_TYPE => Some(IBCEvent::CreateClient(CreateClient(attr))),
UPDATE_EVENT_TYPE => Some(IBCEvent::UpdateClient(UpdateClient(attr))),
_ => None,
}
attr
}

/// NewBlock event signals the committing & execution of a new block.
Expand Down Expand Up @@ -109,7 +107,7 @@ impl TryFrom<RawObject> for CreateClient {
height: obj.height,
client_id: attribute!(obj, "create_client.client_id"),
client_type: attribute!(obj, "create_client.client_type"),
consensus_height: consensus_height_str.try_into()?,
consensus_height: consensus_height_str.as_str().try_into()?,
}))
}
}
Expand Down Expand Up @@ -141,7 +139,7 @@ impl TryFrom<RawObject> for UpdateClient {
height: obj.height,
client_id: attribute!(obj, "update_client.client_id"),
client_type: attribute!(obj, "update_client.client_type"),
consensus_height: consensus_height_str.try_into()?,
consensus_height: consensus_height_str.as_str().try_into()?,
}))
}
}
Expand All @@ -165,7 +163,7 @@ impl TryFrom<RawObject> for ClientMisbehavior {
height: obj.height,
client_id: attribute!(obj, "client_misbehaviour.client_id"),
client_type: attribute!(obj, "client_misbehaviour.client_type"),
consensus_height: consensus_height_str.try_into()?,
consensus_height: consensus_height_str.as_str().try_into()?,
}))
}
}
Expand Down
13 changes: 7 additions & 6 deletions modules/src/ics02_client/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use crate::handler::{Event, EventType, HandlerOutput};
use crate::ics02_client::error::Error;
use crate::ics02_client::events::{CREATE_EVENT_TYPE, UPDATE_EVENT_TYPE};
use crate::ics02_client::msgs::ClientMsg;
use crate::ics24_host::identifier::ClientId;

Expand All @@ -26,11 +27,11 @@ impl From<ClientEvent> for Event {
fn from(ce: ClientEvent) -> Event {
match ce {
ClientEvent::ClientCreated(client_id) => Event::new(
EventType::Custom("ClientCreated".to_string()),
EventType::Custom(CREATE_EVENT_TYPE.to_string()),
vec![("client_id".to_string(), client_id.to_string())],
),
ClientEvent::ClientUpdated(client_id) => Event::new(
EventType::Custom("ClientUpdated".to_string()),
EventType::Custom(UPDATE_EVENT_TYPE.to_string()),
vec![("client_id".to_string(), client_id.to_string())],
),
}
Expand All @@ -42,8 +43,8 @@ pub fn dispatch<Ctx>(ctx: &Ctx, msg: ClientMsg) -> Result<HandlerOutput<ClientRe
where
Ctx: ClientReader,
{
Ok(match msg {
ClientMsg::CreateClient(msg) => create_client::process(ctx, msg)?,
ClientMsg::UpdateClient(msg) => update_client::process(ctx, msg)?,
})
match msg {
ClientMsg::CreateClient(msg) => create_client::process(ctx, msg),
ClientMsg::UpdateClient(msg) => update_client::process(ctx, msg),
}
}
18 changes: 14 additions & 4 deletions modules/src/ics02_client/height.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::{cmp::Ordering, convert::TryFrom};
use std::cmp::Ordering;
use std::convert::TryFrom;
use std::str::FromStr;

use tendermint_proto::Protobuf;

Expand Down Expand Up @@ -130,14 +132,22 @@ impl std::fmt::Display for Height {
}
}

impl TryFrom<String> for Height {
type Error = anomaly::Error<Kind>;
impl TryFrom<&str> for Height {
type Error = Error;

fn try_from(value: String) -> Result<Self, Self::Error> {
fn try_from(value: &str) -> Result<Self, Self::Error> {
let split: Vec<&str> = value.split('-').collect();
Ok(Height {
revision_number: split[0].parse::<u64>().unwrap(),
revision_height: split[1].parse::<u64>().unwrap(),
})
}
}

impl FromStr for Height {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Error> {
Height::try_from(s)
}
}
Loading

0 comments on commit d60a38f

Please sign in to comment.