Skip to content

Commit

Permalink
Fix communication with runtime for build_header and misbehaviour (inf…
Browse files Browse the repository at this point in the history
…ormalsystems#858)

* Send full misbehavior result through runtime channel

* Fix event decoding unwraps and some_attribute to return None when tag is missing

* Proper error handling from runtime when building header
  • Loading branch information
ancazamfir authored Apr 29, 2021
1 parent c32393a commit 314ee36
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 28 deletions.
4 changes: 3 additions & 1 deletion modules/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ macro_rules! attribute {
#[macro_export]
macro_rules! some_attribute {
($a:ident, $b:literal) => {
$a.events.get($b).ok_or($b)?[$a.idx].parse().ok()
$a.events
.get($b)
.map_or_else(|| None, |tags| tags[$a.idx].parse().ok())
};
}
15 changes: 10 additions & 5 deletions modules/src/ics02_client/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ use serde_derive::{Deserialize, Serialize};
use subtle_encoding::hex;
use tendermint_proto::Protobuf;

use crate::attribute;
use crate::events::{IbcEvent, RawObject};
use crate::ics02_client::client_type::ClientType;
use crate::ics02_client::header::AnyHeader;
use crate::ics02_client::height::Height;
use crate::ics24_host::identifier::ClientId;
use crate::{attribute, some_attribute};

/// The content of the `type` field for the event that a chain produces upon executing the create client transaction.
const CREATE_EVENT_TYPE: &str = "create_client";
Expand Down Expand Up @@ -222,9 +222,14 @@ impl From<Attributes> for UpdateClient {
impl TryFrom<RawObject> for UpdateClient {
type Error = BoxError;
fn try_from(obj: RawObject) -> Result<Self, Self::Error> {
let header_str: String = attribute!(obj, "update_client.header");
let header_bytes = hex::decode(header_str).unwrap();
let header: AnyHeader = Protobuf::decode(header_bytes.as_ref()).unwrap();
let header_str: Option<String> = some_attribute!(obj, "update_client.header");
let header: Option<AnyHeader> = match header_str {
Some(str) => {
let header_bytes = hex::decode(str)?;
Some(Protobuf::decode(header_bytes.as_ref())?)
}
None => None,
};
let consensus_height_str: String = attribute!(obj, "update_client.consensus_height");
Ok(UpdateClient {
common: Attributes {
Expand All @@ -233,7 +238,7 @@ impl TryFrom<RawObject> for UpdateClient {
client_type: attribute!(obj, "update_client.client_type"),
consensus_height: consensus_height_str.as_str().try_into()?,
},
header: Some(header),
header,
})
}
}
Expand Down
44 changes: 23 additions & 21 deletions relayer/src/chain/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,25 +370,27 @@ impl<C: Chain + Send + 'static> ChainRuntime<C> {
client_state: AnyClientState,
reply_to: ReplyTo<AnyHeader>,
) -> Result<(), Error> {
let header = {
// Get the light block at trusted_height + 1 from chain.
//
// TODO: This is tendermint specific and needs to be refactored during
// the relayer light client refactoring.
// NOTE: This is needed to get the next validator set. While there is a next validator set
// in the light block at trusted height, the proposer is not known/set in this set.
let trusted_light_block = self.light_client.fetch(trusted_height.increment())?;

// Get the light block at target_height from chain.
let target_light_block =
self.light_client
.verify(trusted_height, target_height, &client_state)?;

let header =
self.chain
.build_header(trusted_height, trusted_light_block, target_light_block)?;

Ok(header.wrap_any())
// Get the light block at trusted_height + 1 from chain.
//
// TODO: This is tendermint specific and needs to be refactored during
// the relayer light client refactoring.
// NOTE: This is needed to get the next validator set. While there is a next validator set
// in the light block at trusted height, the proposer is not known/set in this set.
let trusted_light_block = self.light_client.fetch(trusted_height.increment());

// Get the light block at target_height from chain.
let target_light_block =
self.light_client
.verify(trusted_height, target_height, &client_state);

// Try to build the header, return first error encountered.
let header = match (trusted_light_block, target_light_block) {
(Err(eta), _) => Err(eta),
(_, Err(etr)) => Err(etr),
(Ok(trusted_light_block), Ok(target_light_block)) => self
.chain
.build_header(trusted_height, trusted_light_block, target_light_block)
.map_or_else(Err, |header| Ok(header.wrap_any())),
};

reply_to
Expand Down Expand Up @@ -447,10 +449,10 @@ impl<C: Chain + Send + 'static> ChainRuntime<C> {
) -> Result<(), Error> {
let misbehaviour = self
.light_client
.check_misbehaviour(update_event, &client_state)?;
.check_misbehaviour(update_event, &client_state);

reply_to
.send(Ok(misbehaviour))
.send(misbehaviour)
.map_err(|e| Kind::Channel.context(e))?;

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion relayer/src/foreign_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub enum ForeignClientError {
#[error("failed while finding client {0}: expected chain_id in client state: {1}; actual chain_id: {2}")]
ClientFind(ClientId, ChainId, ChainId),

#[error("error raised while submitting the misbehaviour evidence: {0}")]
#[error("error raised while checking for misbehaviour evidence: {0}")]
Misbehaviour(String),

#[error("failed while trying to upgrade client id {0} with error: {1}")]
Expand Down

0 comments on commit 314ee36

Please sign in to comment.