Skip to content
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
53 changes: 49 additions & 4 deletions core/src/ibc/connection_03/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ impl<'a> Manager<'a> {
counterparty_prefix: CommitmentPrefix,
counterparty_client_identifier: Identifier,
client_identifier: Identifier,
proof_init: CommitmentProof,
proof_consensus: CommitmentProof,
proof_init: Vec<u8>,
proof_consensus: Vec<u8>,
proof_height: u64,
consensus_height: u64,
) -> Result<(), String> {
Expand Down Expand Up @@ -118,6 +118,45 @@ impl<'a> Manager<'a> {
Ok(())
}

pub fn handle_open_ack(
&mut self,
identifier: Identifier,
proof_try: Vec<u8>,
proof_consensus: Vec<u8>,
proof_height: u64,
consensus_height: u64,
) -> Result<(), String> {
let current_height = self.ctx.get_current_height();
if consensus_height > current_height {
return Err(format!(
"Consensus height {} is greater than current height {}",
consensus_height, current_height
))
}
let mut connection = self
.query(&identifier)
.ok_or_else(|| format!("Cannot find connection with the identifier: {}", identifier))?;

if connection.state != ConnectionState::INIT && connection.state != ConnectionState::TRYOPEN {
return Err(format!("Invalid connection state expected INIT or TRYOPEN but found {:?}", connection.state))
}
let expected_connection = ConnectionEnd {
state: ConnectionState::TRYOPEN,
counterparty_connection_identifier: identifier.clone(),
counterparty_prefix: get_commiment_prefix(),
client_identifier: connection.counterparty_client_identifier.clone(),
counterparty_client_identifier: connection.client_identifier.clone(),
};
self.verify_connection_state(&connection, proof_height, proof_try, identifier.clone(), &expected_connection);

connection.state = ConnectionState::OPEN;
let kv_store = self.ctx.get_kv_store_mut();
let path = connection_path(&identifier);
kv_store.set(&path, &connection.rlp_bytes());

Ok(())
}

fn query(&mut self, identifier: &str) -> Option<ConnectionEnd> {
let kv_store = self.ctx.get_kv_store();

Expand All @@ -135,13 +174,19 @@ impl<'a> Manager<'a> {
&mut self,
connection: &ConnectionEnd,
proof_height: u64,
proof: CommitmentProof,
proof: Vec<u8>,
connection_identifier: Identifier,
connection_end: &ConnectionEnd,
) -> bool {
let proof_dec: CommitmentProof = if let Ok(proof) = rlp::decode(&proof) {
proof
} else {
return false
};

// check values in the connection_end
let path = format!("connections/{}", connection_identifier);
self.client_verify_membership(proof_height, proof, path, &rlp::encode(connection_end))
self.client_verify_membership(proof_height, proof_dec, path, &rlp::encode(connection_end))
}

fn client_verify_membership(
Expand Down
40 changes: 40 additions & 0 deletions core/src/ibc/transaction_handler/datagrams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum DatagramTag {
UpdateClient = 2,
ConnOpenInit = 3,
ConnOpenTry = 4,
ConnOpenAck = 5,
}

impl Encodable for DatagramTag {
Expand All @@ -39,6 +40,7 @@ impl Decodable for DatagramTag {
2 => Ok(DatagramTag::UpdateClient),
3 => Ok(DatagramTag::ConnOpenInit),
4 => Ok(DatagramTag::ConnOpenTry),
5 => Ok(DatagramTag::ConnOpenAck),
_ => Err(DecoderError::Custom("Unexpected DatagramTag Value")),
}
}
Expand Down Expand Up @@ -74,6 +76,13 @@ pub enum Datagram {
proof_height: u64,
consensus_height: u64,
},
ConnOpenAck {
identifier: String,
proof_try: Vec<u8>,
proof_consensus: Vec<u8>,
proof_height: u64,
consensus_height: u64,
},
}

impl Encodable for Datagram {
Expand Down Expand Up @@ -136,6 +145,21 @@ impl Encodable for Datagram {
.append(proof_height)
.append(consensus_height);
}
Datagram::ConnOpenAck {
identifier,
proof_try,
proof_consensus,
proof_height,
consensus_height,
} => {
s.begin_list(6);
s.append(&DatagramTag::ConnOpenAck)
.append(identifier)
.append(proof_try)
.append(proof_consensus)
.append(proof_height)
.append(consensus_height);
}
};
}
}
Expand Down Expand Up @@ -208,6 +232,22 @@ impl Decodable for Datagram {
consensus_height: rlp.val_at(9)?,
})
}
DatagramTag::ConnOpenAck => {
let item_count = rlp.item_count()?;
if item_count != 6 {
return Err(DecoderError::RlpInvalidLength {
expected: 6,
got: item_count,
})
}
Ok(Datagram::ConnOpenAck {
identifier: rlp.val_at(1)?,
proof_try: rlp.val_at(2)?,
proof_consensus: rlp.val_at(3)?,
proof_height: rlp.val_at(4)?,
consensus_height: rlp.val_at(5)?,
})
}
}
}
}
26 changes: 15 additions & 11 deletions core/src/ibc/transaction_handler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ mod datagrams;

use self::datagrams::Datagram;
use crate::ibc;
use crate::ibc::commitment_23::types::{CommitmentPrefix, CommitmentProof};
use crate::ibc::commitment_23::types::CommitmentPrefix;
use ckey::{Address, Public};
use cstate::{StateResult, TopLevelState};
use ctypes::errors::RuntimeError;
Expand Down Expand Up @@ -78,16 +78,8 @@ pub fn execute(
proof_height,
consensus_height,
} => {
let mut context = ibc_context::TopLevelContext::new(state, current_block_number);
let mut connection_manager = ibc_connection::Manager::new(&mut context);

let proof_init_dec: CommitmentProof = rlp::Rlp::new(&proof_init)
.as_val()
.map_err(|err| RuntimeError::IBC(format!("ConnOpenTry failed to decode proof_init {}", err)))?;
let proof_consensus_dec: CommitmentProof = rlp::Rlp::new(&proof_consensus)
.as_val()
.map_err(|err| RuntimeError::IBC(format!("ConnOpenTry failed to decode consensus_init {}", err)))?;

connection_manager
.handle_open_try(
desired_identifier,
Expand All @@ -97,13 +89,25 @@ pub fn execute(
},
counterparty_client_identifier,
client_identifier,
proof_init_dec,
proof_consensus_dec,
proof_init,
proof_consensus,
proof_height,
consensus_height,
)
.map_err(|err| RuntimeError::IBC(format!("ConnOpenTry: {}", err)).into())
}
Datagram::ConnOpenAck {
identifier,
proof_try,
proof_consensus,
proof_height,
consensus_height,
} => {
let mut connection_manager = ibc_connection::Manager::new(&mut context);
connection_manager
.handle_open_ack(identifier, proof_try, proof_consensus, proof_height, consensus_height)
.map_err(|err| RuntimeError::IBC(format!("ConnOpenAck: {}", err)).into())
}
}
}

Expand Down