Skip to content

Commit

Permalink
Major refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
hu55a1n1 committed Mar 28, 2022
1 parent 7583abe commit c4d31de
Show file tree
Hide file tree
Showing 16 changed files with 187 additions and 129 deletions.
76 changes: 51 additions & 25 deletions modules/src/core/ics04_channel/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::core::ics04_channel::handler::recv_packet::RecvPacketResult;
use crate::core::ics04_channel::handler::{ChannelIdState, ChannelResult};
use crate::core::ics04_channel::{error::Error, packet::Receipt};
use crate::core::ics05_port::capabilities::{CapabilityName, ChannelCapability};
use crate::core::ics05_port::context::CapabilityReader;
use crate::core::ics05_port::context::{CapabilityKeeper, CapabilityReader};
use crate::core::ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId};
use crate::core::ics24_host::path::ChannelCapabilityPath;
use crate::core::ics26_routing::context::ModuleId;
Expand Down Expand Up @@ -42,8 +42,6 @@ pub trait ChannelReader: CapabilityReader {
height: Height,
) -> Result<AnyConsensusState, Error>;

fn authenticated_capability(&self, port_id: &PortId) -> Result<ChannelCapability, Error>;

fn get_next_sequence_send(
&self,
port_channel_id: &(PortId, ChannelId),
Expand Down Expand Up @@ -114,50 +112,55 @@ pub trait ChannelReader: CapabilityReader {
as u64
}

/// Return the module_id along with the capability associated with a given (channel-id, port_id)
/// Return the `ModuleId` along with the `ChannelCapability` associated with a given
/// `PortId`-`ChannelId`
fn lookup_module_by_channel(
&self,
channel_id: &ChannelId,
port_id: &PortId,
) -> Result<(ModuleId, ChannelCapability), Error>;
channel_id: ChannelId,
port_id: PortId,
) -> Result<(ModuleId, ChannelCapability), Error> {
CapabilityReader::lookup_module(self, &channel_capability_name(port_id, channel_id))
.map(|(module_id, capability)| (module_id, capability.into()))
.map_err(Error::ics05_port)
}

/// Check if the specified port_id is already bounded
/// Get the `ChannelCapability` associated with the specified `PortId`-`ChannelId`
fn get_channel_capability(
&self,
port_id: PortId,
channel_id: ChannelId,
) -> Result<ChannelCapability, Error> {
CapabilityReader::get_capability(self, &self.channel_capability_name(port_id, channel_id))
CapabilityReader::get_capability(self, &channel_capability_name(port_id, channel_id))
.map(Into::into)
.map_err(Error::ics05_port)
}

/// Authenticate a capability key against a port_id by checking if the capability was previously
/// generated and bound to the specified port
fn authenticate(
/// Authenticate a `ChannelCapability` against the specified `PortId`-`ChannelId` by checking if
/// the capability was previously generated and bound to the specified port/channel
fn authenticate_channel_capability(
&self,
port_id: PortId,
channel_id: ChannelId,
capability: &ChannelCapability,
) -> bool {
self.authenticate_capability(
&self.channel_capability_name(port_id, channel_id),
capability,
)
.is_ok()
) -> Result<(), Error> {
self.authenticate_capability(&channel_capability_name(port_id, channel_id), capability)
.map_err(Error::ics05_port)
}

fn channel_capability_name(&self, port_id: PortId, channel_id: ChannelId) -> CapabilityName {
ChannelCapabilityPath(port_id, channel_id)
.to_string()
.parse()
.expect("ChannelEndsPath cannot be empty string")
fn create_channel_capability(
&self,
port_id: PortId,
channel_id: ChannelId,
) -> Result<ChannelCapability, Error> {
self.create_capability(channel_capability_name(port_id, channel_id))
.map(Into::into)
.map_err(Error::ics05_port)
}
}

/// A context supplying all the necessary write-only dependencies (i.e., storage writing facility)
/// for processing any `ChannelMsg`.
pub trait ChannelKeeper {
pub trait ChannelKeeper: CapabilityKeeper {
fn store_channel_result(&mut self, result: ChannelResult) -> Result<(), Error> {
// The handler processed this channel & some modifications occurred, store the new end.
self.store_channel(
Expand Down Expand Up @@ -185,7 +188,12 @@ pub trait ChannelKeeper {
(result.port_id.clone(), result.channel_id.clone()),
1.into(),
)?;
self.store_next_sequence_ack((result.port_id, result.channel_id), 1.into())?;
self.store_next_sequence_ack(
(result.port_id.clone(), result.channel_id.clone()),
1.into(),
)?;

self.store_channel_capability(result.port_id, result.channel_id)?;
}

Ok(())
Expand Down Expand Up @@ -328,4 +336,22 @@ pub trait ChannelKeeper {
/// Increases the counter which keeps track of how many channels have been created.
/// Should never fail.
fn increase_channel_counter(&mut self);

/// Create a new capability associated with the given `PortId`-`ChannelId`
fn store_channel_capability(
&mut self,
port_id: PortId,
channel_id: ChannelId,
) -> Result<ChannelCapability, Error> {
self.new_capability(channel_capability_name(port_id, channel_id))
.map(Into::into)
.map_err(Error::ics05_port)
}
}

fn channel_capability_name(port_id: PortId, channel_id: ChannelId) -> CapabilityName {
ChannelCapabilityPath(port_id, channel_id)
.to_string()
.parse()
.expect("ChannelEndsPath cannot be empty string")
}
31 changes: 20 additions & 11 deletions modules/src/core/ics04_channel/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,29 +67,29 @@ where
{
let (module_id, output) = match msg {
ChannelMsg::ChannelOpenInit(msg) => ctx
.lookup_module_by_port(&msg.port_id)
.lookup_module_by_port(msg.port_id.clone())
.map_err(|_| Error::no_port_capability(msg.port_id.clone()))
.and_then(|(mid, cap)| Ok((validate_route(ctx, mid)?, cap)))
.and_then(|(mid, cap)| Ok((mid, chan_open_init::process(ctx, msg, cap)?))),
ChannelMsg::ChannelOpenTry(msg) => ctx
.lookup_module_by_port(&msg.port_id)
.lookup_module_by_port(msg.port_id.clone())
.map_err(|_| Error::no_port_capability(msg.port_id.clone()))
.and_then(|(mid, cap)| Ok((validate_route(ctx, mid)?, cap)))
.and_then(|(mid, cap)| Ok((mid, chan_open_try::process(ctx, msg, cap)?))),
ChannelMsg::ChannelOpenAck(msg) => ctx
.lookup_module_by_channel(&msg.channel_id, &msg.port_id)
.lookup_module_by_channel(msg.channel_id.clone(), msg.port_id.clone())
.and_then(|(mid, cap)| Ok((validate_route(ctx, mid)?, cap)))
.and_then(|(mid, cap)| Ok((mid, chan_open_ack::process(ctx, msg, cap)?))),
ChannelMsg::ChannelOpenConfirm(msg) => ctx
.lookup_module_by_channel(&msg.channel_id, &msg.port_id)
.lookup_module_by_channel(msg.channel_id.clone(), msg.port_id.clone())
.and_then(|(mid, cap)| Ok((validate_route(ctx, mid)?, cap)))
.and_then(|(mid, cap)| Ok((mid, chan_open_confirm::process(ctx, msg, cap)?))),
ChannelMsg::ChannelCloseInit(msg) => ctx
.lookup_module_by_channel(&msg.channel_id, &msg.port_id)
.lookup_module_by_channel(msg.channel_id.clone(), msg.port_id.clone())
.and_then(|(mid, cap)| Ok((validate_route(ctx, mid)?, cap)))
.and_then(|(mid, cap)| Ok((mid, chan_close_init::process(ctx, msg, cap)?))),
ChannelMsg::ChannelCloseConfirm(msg) => ctx
.lookup_module_by_channel(&msg.channel_id, &msg.port_id)
.lookup_module_by_channel(msg.channel_id.clone(), msg.port_id.clone())
.and_then(|(mid, cap)| Ok((validate_route(ctx, mid)?, cap)))
.and_then(|(mid, cap)| Ok((mid, chan_close_confirm::process(ctx, msg, cap)?))),
}?;
Expand Down Expand Up @@ -173,21 +173,30 @@ where
let (module_id, output) = match msg {
PacketMsg::RecvPacket(msg) => ctx
.lookup_module_by_channel(
&msg.packet.destination_channel,
&msg.packet.destination_port,
msg.packet.destination_channel.clone(),
msg.packet.destination_port.clone(),
)
.and_then(|(mid, cap)| Ok((validate_route(ctx, mid)?, cap)))
.and_then(|(mid, cap)| Ok((mid, recv_packet::process(ctx, msg, cap)?))),
PacketMsg::AckPacket(msg) => ctx
.lookup_module_by_channel(&msg.packet.source_channel, &msg.packet.source_port)
.lookup_module_by_channel(
msg.packet.source_channel.clone(),
msg.packet.source_port.clone(),
)
.and_then(|(mid, cap)| Ok((validate_route(ctx, mid)?, cap)))
.and_then(|(mid, cap)| Ok((mid, acknowledgement::process(ctx, msg, cap)?))),
PacketMsg::ToPacket(msg) => ctx
.lookup_module_by_channel(&msg.packet.source_channel, &msg.packet.source_port)
.lookup_module_by_channel(
msg.packet.source_channel.clone(),
msg.packet.source_port.clone(),
)
.and_then(|(mid, cap)| Ok((validate_route(ctx, mid)?, cap)))
.and_then(|(mid, cap)| Ok((mid, timeout::process(ctx, msg, cap)?))),
PacketMsg::ToClosePacket(msg) => ctx
.lookup_module_by_channel(&msg.packet.source_channel, &msg.packet.source_port)
.lookup_module_by_channel(
msg.packet.source_channel.clone(),
msg.packet.source_port.clone(),
)
.and_then(|(mid, cap)| Ok((validate_route(ctx, mid)?, cap)))
.and_then(|(mid, cap)| Ok((mid, timeout_on_close::process(ctx, msg, cap)?))),
}?;
Expand Down
8 changes: 6 additions & 2 deletions modules/src/core/ics04_channel/handler/acknowledgement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct AckPacketResult {
pub fn process(
ctx: &dyn ChannelReader,
msg: &MsgAcknowledgement,
_cap: ChannelCapability,
channel_cap: ChannelCapability,
) -> HandlerResult<PacketResult, Error> {
let mut output = HandlerOutput::builder();

Expand All @@ -37,7 +37,11 @@ pub fn process(
return Err(Error::channel_closed(packet.source_channel.clone()));
}

let _channel_cap = ctx.authenticated_capability(&packet.source_port)?;
ctx.authenticate_channel_capability(
packet.source_port.clone(),
packet.source_channel.clone(),
&channel_cap,
)?;

let counterparty = Counterparty::new(
packet.destination_port.clone(),
Expand Down
4 changes: 2 additions & 2 deletions modules/src/core/ics04_channel/handler/chan_close_confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::prelude::*;
pub(crate) fn process(
ctx: &dyn ChannelReader,
msg: &MsgChannelCloseConfirm,
_cap: ChannelCapability,
channel_cap: ChannelCapability,
) -> HandlerResult<ChannelResult, Error> {
let mut output = HandlerOutput::builder();

Expand All @@ -28,7 +28,7 @@ pub(crate) fn process(
}

// Channel capabilities
let channel_cap = ctx.authenticated_capability(&msg.port_id)?;
ctx.authenticate_channel_capability(msg.port_id.clone(), msg.channel_id.clone(), &channel_cap)?;

// An OPEN IBC connection running on the local (host) chain should exist.
if channel_end.connection_hops().len() != 1 {
Expand Down
5 changes: 3 additions & 2 deletions modules/src/core/ics04_channel/handler/chan_close_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::handler::{HandlerOutput, HandlerResult};
pub(crate) fn process(
ctx: &dyn ChannelReader,
msg: &MsgChannelCloseInit,
_cap: ChannelCapability,
channel_cap: ChannelCapability,
) -> HandlerResult<ChannelResult, Error> {
let mut output = HandlerOutput::builder();

Expand All @@ -29,7 +29,8 @@ pub(crate) fn process(
}

// Channel capabilities
let channel_cap = ctx.authenticated_capability(&msg.port_id)?;
ctx.authenticate_channel_capability(msg.port_id.clone(), msg.channel_id.clone(), &channel_cap)?;

// An OPEN IBC connection running on the local (host) chain should exist.

if channel_end.connection_hops().len() != 1 {
Expand Down
4 changes: 2 additions & 2 deletions modules/src/core/ics04_channel/handler/chan_open_ack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::prelude::*;
pub(crate) fn process(
ctx: &dyn ChannelReader,
msg: &MsgChannelOpenAck,
_cap: ChannelCapability,
channel_cap: ChannelCapability,
) -> HandlerResult<ChannelResult, Error> {
let mut output = HandlerOutput::builder();

Expand All @@ -31,7 +31,7 @@ pub(crate) fn process(
}

// Channel capabilities
let channel_cap = ctx.authenticated_capability(&msg.port_id)?;
ctx.authenticate_channel_capability(msg.port_id.clone(), msg.channel_id.clone(), &channel_cap)?;

// An OPEN IBC connection running on the local (host) chain should exist.

Expand Down
4 changes: 2 additions & 2 deletions modules/src/core/ics04_channel/handler/chan_open_confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::prelude::*;
pub(crate) fn process(
ctx: &dyn ChannelReader,
msg: &MsgChannelOpenConfirm,
_cap: ChannelCapability,
channel_cap: ChannelCapability,
) -> HandlerResult<ChannelResult, Error> {
let mut output = HandlerOutput::builder();

Expand All @@ -31,7 +31,7 @@ pub(crate) fn process(
}

// Channel capabilities
let channel_cap = ctx.authenticated_capability(&msg.port_id)?;
ctx.authenticate_channel_capability(msg.port_id.clone(), msg.channel_id.clone(), &channel_cap)?;

// An OPEN IBC connection running on the local (host) chain should exist.
if channel_end.connection_hops().len() != 1 {
Expand Down
12 changes: 7 additions & 5 deletions modules/src/core/ics04_channel/handler/chan_open_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,22 @@ use crate::core::ics04_channel::events::Attributes;
use crate::core::ics04_channel::handler::{ChannelIdState, ChannelResult};
use crate::core::ics04_channel::msgs::chan_open_init::MsgChannelOpenInit;
use crate::core::ics05_port::capabilities::PortCapability;
use crate::core::ics05_port::context::PortReader;
use crate::core::ics24_host::identifier::ChannelId;
use crate::events::IbcEvent;
use crate::handler::{HandlerOutput, HandlerResult};
use crate::prelude::*;

pub(crate) fn process(
ctx: &dyn ChannelReader,
pub(crate) fn process<Ctx: ChannelReader + PortReader>(
ctx: &Ctx,
msg: &MsgChannelOpenInit,
_cap: PortCapability,
port_cap: PortCapability,
) -> HandlerResult<ChannelResult, Error> {
let mut output = HandlerOutput::builder();

// Channel capabilities
let channel_cap = ctx.authenticated_capability(&msg.port_id)?;
ctx.authenticate_port_capability(msg.port_id.clone(), &port_cap)
.map_err(Error::ics05_port)?;

if msg.channel.connection_hops().len() != 1 {
return Err(Error::invalid_connection_hops_length(
Expand Down Expand Up @@ -66,7 +68,7 @@ pub(crate) fn process(
channel_id: chan_id.clone(),
channel_end: new_channel_end,
channel_id_state: ChannelIdState::Generated,
channel_cap,
channel_cap: ctx.create_channel_capability(msg.port_id.clone(), chan_id.clone())?,
};

let event_attributes = Attributes {
Expand Down
24 changes: 15 additions & 9 deletions modules/src/core/ics04_channel/handler/chan_open_try.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ use crate::core::ics04_channel::handler::verify::verify_channel_proofs;
use crate::core::ics04_channel::handler::{ChannelIdState, ChannelResult};
use crate::core::ics04_channel::msgs::chan_open_try::MsgChannelOpenTry;
use crate::core::ics05_port::capabilities::PortCapability;
use crate::core::ics05_port::context::PortReader;
use crate::core::ics24_host::identifier::ChannelId;
use crate::events::IbcEvent;
use crate::handler::{HandlerOutput, HandlerResult};
use crate::prelude::*;

pub(crate) fn process(
ctx: &dyn ChannelReader,
pub(crate) fn process<Ctx: ChannelReader + PortReader>(
ctx: &Ctx,
msg: &MsgChannelOpenTry,
_cap: PortCapability,
port_cap: PortCapability,
) -> HandlerResult<ChannelResult, Error> {
let mut output = HandlerOutput::builder();

Expand Down Expand Up @@ -90,7 +91,8 @@ pub(crate) fn process(
}

// Channel capabilities
let channel_cap = ctx.authenticated_capability(&msg.port_id)?;
ctx.authenticate_port_capability(msg.port_id.clone(), &port_cap)
.map_err(Error::ics05_port)?;

// Proof verification in two steps:
// 1. Setup: build the Channel as we expect to find it on the other party.
Expand Down Expand Up @@ -127,14 +129,18 @@ pub(crate) fn process(
// Transition the channel end to the new state & pick a version.
new_channel_end.set_state(State::TryOpen);

let (channel_id_state, channel_cap) = if matches!(msg.previous_channel_id, None) {
let cap = ctx.create_channel_capability(msg.port_id.clone(), channel_id.clone())?;
(ChannelIdState::Generated, cap)
} else {
let cap = ctx.get_channel_capability(msg.port_id.clone(), channel_id.clone())?;
(ChannelIdState::Reused, cap)
};

let result = ChannelResult {
port_id: msg.port_id.clone(),
channel_cap,
channel_id_state: if matches!(msg.previous_channel_id, None) {
ChannelIdState::Generated
} else {
ChannelIdState::Reused
},
channel_id_state,
channel_id: channel_id.clone(),
channel_end: new_channel_end,
};
Expand Down
Loading

0 comments on commit c4d31de

Please sign in to comment.