Skip to content

Commit

Permalink
Merge branch 'master' into andy/acct_prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
romac committed Mar 10, 2021
2 parents c325894 + bfd3d8e commit fa38d3a
Show file tree
Hide file tree
Showing 38 changed files with 782 additions and 173 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
### FEATURES

- [ibc]
- [nothing yet]
- Added handler(s) for sending packets ([#695])

- [ibc-relayer]
- Support for relayer restart ([#561])
Expand Down Expand Up @@ -62,6 +62,7 @@
[#672]: https://github.com/informalsystems/ibc-rs/issues/672
[#685]: https://github.com/informalsystems/ibc-rs/issues/685
[#689]: https://github.com/informalsystems/ibc-rs/issues/689
[#695]: https://github.com/informalsystems/ibc-rs/issues/695
[#699]: https://github.com/informalsystems/ibc-rs/issues/699
[#700]: https://github.com/informalsystems/ibc-rs/pull/700

Expand Down
17 changes: 9 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions modules/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ description = """
[features]
# This feature grants access to development-time mocking libraries, such as `MockContext` or `MockHeader`.
# Depends on the `testgen` suite for generating Tendermint light blocks.
mocks = [ "tendermint-testgen" ]
mocks = [ "tendermint-testgen", "sha2" ]

[dependencies]
# Proto definitions for all IBC-related interfaces, e.g., connections or channels.
Expand All @@ -27,7 +27,7 @@ anomaly = "0.2.0"
chrono = "0.4"
thiserror = "1.0.24"
serde_derive = "1.0.104"
serde = "1.0.104"
serde = "1.0.124"
serde_json = "1"
tracing = "0.1.13"
prost = "0.7"
Expand All @@ -36,6 +36,7 @@ bytes = "1.0.0"
dyn-clonable = "0.9.0"
regex = "1"
subtle-encoding = "0.5"
sha2 = { version = "0.9.3", optional = true }

[dependencies.tendermint]
version = "=0.18.1"
Expand All @@ -51,6 +52,7 @@ optional = true
tokio = { version = "1.0", features = ["macros"] }
tendermint-rpc = { version = "=0.18.1", features = ["http-client", "websocket-client"] }
tendermint-testgen = { version = "=0.18.1" } # Needed for generating (synthetic) light blocks.
sha2 = { version = "0.9.3" }

[[test]]
name = "mbt"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use crate::ics04_channel::context::{ChannelKeeper, ChannelReader};

/// Captures all the dependencies which the ICS20 module requires to be able to dispatch and
/// process IBC messages.
pub trait Ics20Context: ChannelReader + ChannelKeeper + Clone {}
23 changes: 21 additions & 2 deletions modules/src/application/ics20_fungible_token_transfer/error.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
use anomaly::{BoxError, Context};
use thiserror::Error;

use crate::ics24_host::identifier::{ChannelId, PortId};

pub type Error = anomaly::Error<Kind>;

#[derive(Clone, Debug, Error)]
pub enum Kind {}
#[derive(Clone, Debug, Error, PartialEq, Eq)]
pub enum Kind {
#[error("unrecognized ICS-20 transfer message type URL {0}")]
UnknownMessageTypeUrl(String),

#[error("error raised by message handler")]
HandlerRaisedError,

#[error("Sending sequence number not found for port {0} and channel {1}")]
SequenceSendNotFound(PortId, ChannelId),

#[error("Missing channel for port_id {0} and channel_id {1} ")]
ChannelNotFound(PortId, ChannelId),

#[error(
"Destination channel not found in the counterparty of port_id {0} and channel_id {1} "
)]
DestinationChannelNotFound(PortId, ChannelId),
}

impl Kind {
pub fn context(self, source: impl Into<BoxError>) -> Context<Self> {
Expand Down
2 changes: 2 additions & 0 deletions modules/src/application/ics20_fungible_token_transfer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! ICS 20: IBC Transfer implementation
pub mod context;
pub mod error;
pub mod msgs;
pub mod relay_application_logic;
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::convert::{TryFrom, TryInto};
//! This is the definition of a transfer messages that an application submits to a chain.

use tendermint_proto::Protobuf;
use std::convert::{TryFrom, TryInto};

use ibc_proto::ibc::applications::transfer::v1::MsgTransfer as RawMsgTransfer;
use tendermint_proto::Protobuf;

use crate::application::ics20_fungible_token_transfer::error::{Error, Kind};
use crate::ics02_client::height::Height;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! This module implements the processing logic for ICS20 (token transfer) message.

pub mod send_transfer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use crate::application::ics20_fungible_token_transfer::context::Ics20Context;
use crate::application::ics20_fungible_token_transfer::error::{Error, Kind};
use crate::application::ics20_fungible_token_transfer::msgs::transfer::MsgTransfer;
use crate::handler::HandlerOutput;
use crate::ics04_channel::handler::send_packet::send_packet;
use crate::ics04_channel::packet::Packet;
use crate::ics04_channel::packet::PacketResult;

pub(crate) fn send_transfer<Ctx>(
ctx: &Ctx,
msg: MsgTransfer,
) -> Result<HandlerOutput<PacketResult>, Error>
where
Ctx: Ics20Context,
{
let source_channel_end = ctx
.channel_end(&(msg.source_port.clone(), msg.source_channel.clone()))
.ok_or_else(|| {
Kind::ChannelNotFound(msg.source_port.clone(), msg.source_channel.clone())
})?;

let destination_port = source_channel_end.counterparty().port_id().clone();
let destination_channel = source_channel_end
.counterparty()
.channel_id()
.ok_or_else(|| {
Kind::DestinationChannelNotFound(msg.source_port.clone(), msg.source_channel.clone())
})?;

// get the next sequence
let sequence = ctx
.get_next_sequence_send(&(msg.source_port.clone(), msg.source_channel.clone()))
.ok_or_else(|| {
Kind::SequenceSendNotFound(msg.source_port.clone(), msg.source_channel.clone())
})?;

//TODO: Application LOGIC.

let packet = Packet {
sequence,
source_port: msg.source_port,
source_channel: msg.source_channel,
destination_port,
destination_channel: destination_channel.clone(),
data: vec![],
timeout_height: msg.timeout_height,
timeout_timestamp: msg.timeout_timestamp,
};

let handler_output =
send_packet(ctx, packet).map_err(|e| Kind::HandlerRaisedError.context(e))?;

//TODO: add event/atributes and writes to the store issued by the application logic for packet sending.
Ok(handler_output)
}
15 changes: 15 additions & 0 deletions modules/src/ics02_client/client_def.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::convert::TryFrom;

use chrono::{DateTime, Utc};
use prost_types::Any;
use serde::Serialize;
use tendermint_proto::Protobuf;
Expand Down Expand Up @@ -287,6 +288,20 @@ pub enum AnyConsensusState {
}

impl AnyConsensusState {
pub fn timestamp(&self) -> Result<u64, Kind> {
match self {
Self::Tendermint(cs_state) => {
let date: DateTime<Utc> = cs_state.timestamp.into();
let value = date.timestamp();
u64::try_from(value)
.map_err(|_| Kind::NegativeConsensusStateTimestamp(value.to_string()))
}

#[cfg(any(test, feature = "mocks"))]
Self::Mock(mock_state) => Ok(mock_state.timestamp()),
}
}

pub fn client_type(&self) -> ClientType {
match self {
AnyConsensusState::Tendermint(_cs) => ClientType::Tendermint,
Expand Down
3 changes: 3 additions & 0 deletions modules/src/ics02_client/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ pub enum Kind {
#[error("implementation specific")]
ImplementationSpecific,

#[error("Negative timestamp in consensus state {0}; timestamp must be a positive value")]
NegativeConsensusStateTimestamp(String),

#[error("header verification failed")]
HeaderVerificationFailure,

Expand Down
17 changes: 8 additions & 9 deletions modules/src/ics02_client/handler/create_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ pub fn process(
mod tests {
use std::convert::TryInto;
use std::time::Duration;

use tendermint::trust_threshold::TrustThresholdFraction as TrustThreshold;

use crate::events::IbcEvent;
Expand All @@ -84,8 +83,8 @@ mod tests {
let height = Height::new(0, 42);

let msg = MsgCreateAnyClient::new(
MockClientState(MockHeader(height)).into(),
MockConsensusState(MockHeader(height)).into(),
MockClientState(MockHeader::new(height)).into(),
MockConsensusState(MockHeader::new(height)).into(),
signer,
)
.unwrap();
Expand Down Expand Up @@ -130,12 +129,12 @@ mod tests {

let create_client_msgs: Vec<MsgCreateAnyClient> = vec![
MsgCreateAnyClient::new(
MockClientState(MockHeader(Height {
MockClientState(MockHeader::new(Height {
revision_height: 42,
..height
}))
.into(),
MockConsensusState(MockHeader(Height {
MockConsensusState(MockHeader::new(Height {
revision_height: 42,
..height
}))
Expand All @@ -144,12 +143,12 @@ mod tests {
)
.unwrap(),
MsgCreateAnyClient::new(
MockClientState(MockHeader(Height {
MockClientState(MockHeader::new(Height {
revision_height: 42,
..height
}))
.into(),
MockConsensusState(MockHeader(Height {
MockConsensusState(MockHeader::new(Height {
revision_height: 42,
..height
}))
Expand All @@ -158,12 +157,12 @@ mod tests {
)
.unwrap(),
MsgCreateAnyClient::new(
MockClientState(MockHeader(Height {
MockClientState(MockHeader::new(Height {
revision_height: 50,
..height
}))
.into(),
MockConsensusState(MockHeader(Height {
MockConsensusState(MockHeader::new(Height {
revision_height: 50,
..height
}))
Expand Down
11 changes: 6 additions & 5 deletions modules/src/ics02_client/handler/update_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,9 @@ mod tests {
let signer = get_dummy_account_id();

let ctx = MockContext::default().with_client(&client_id, Height::new(0, 42));

let msg = MsgUpdateAnyClient {
client_id: client_id.clone(),
header: MockHeader(Height::new(0, 46)).into(),
header: MockHeader::new(Height::new(0, 46)).into(),
signer,
};

Expand All @@ -122,7 +121,9 @@ mod tests {
assert_eq!(upd_res.client_id, client_id);
assert_eq!(
upd_res.client_state,
AnyClientState::Mock(MockClientState(MockHeader(msg.header.height())))
AnyClientState::Mock(MockClientState(MockHeader::new(
msg.header.height()
)))
)
}
Create(_) => panic!("update handler result has type CreateResult"),
Expand All @@ -143,7 +144,7 @@ mod tests {

let msg = MsgUpdateAnyClient {
client_id: ClientId::from_str("nonexistingclient").unwrap(),
header: MockHeader(Height::new(0, 46)).into(),
header: MockHeader::new(Height::new(0, 46)).into(),
signer,
};

Expand Down Expand Up @@ -179,7 +180,7 @@ mod tests {
for cid in &client_ids {
let msg = MsgUpdateAnyClient {
client_id: cid.clone(),
header: MockHeader(update_height).into(),
header: MockHeader::new(update_height).into(),
signer: signer.clone(),
};

Expand Down
Loading

0 comments on commit fa38d3a

Please sign in to comment.