-
Notifications
You must be signed in to change notification settings - Fork 323
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First stab at ICS3 connection handshake protocol (message processing …
…logic) (#188) * First processing logic for ICS 03 (#160). * Fix for temporary pick_version(). * First attempt at the process_try_msg function. * Sketch for proof verification in process_try_msg. Removed Connection* traits. * Added logic for the Try message. * Logic for processing ICS3 confirm msg. Cosmetic improvements * Adapting code to new architecture based on contexts. * Refactored, new terminology, added events. * WIP: Adding tests * Higher-level interface for the context. * One chunk of proof verification is done * Implementation of ics3 verify_proofs done. * Addressing Romain's concerns. * Tests for conn open init message processing. * Fixes for integration tests: PartialEq for identifiers. * More changes cf adr003 and code reorg * Move info to new context and context_mock modules * migrate conn-open-init to new infra * Refine client and connection mock context * Fix conn_open_try handler * Create new mock_client * remove mocks.rs * Add global chain context * Uncomment tests * Cleanup * Started to fill client verification functions. Started TryFromRaw for connection messages. Some work on commitment prefix, path, root. * Add try_from for connection messages and remove new() * Add test for try dispatch * Some changes to mock context setup * Some cleanup * Review comments * Mark mocks as `#[cfg(test)] * Fix clippy warnings * Remove use of clone in a Debug impl Co-authored-by: Anca Zamfir <zamfiranca@gmail.com> Co-authored-by: Romain Ruetschi <romain@informal.systems>
- Loading branch information
1 parent
66274aa
commit cf6c815
Showing
47 changed files
with
2,169 additions
and
749 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub struct AccAddress(Vec<u8>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
use serde_derive::{Deserialize, Serialize}; | ||
use tendermint::block::Height; | ||
|
||
#[cfg(test)] | ||
use crate::ics02_client::client_def::AnyConsensusState; | ||
#[cfg(test)] | ||
use crate::mock_client::header::MockHeader; | ||
#[cfg(test)] | ||
use crate::mock_client::state::MockConsensusState; | ||
|
||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] | ||
pub enum SelfHeader { | ||
// Tendermint(tendermint::header::Header), | ||
#[cfg(test)] | ||
Mock(MockHeader), | ||
} | ||
|
||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] | ||
pub struct HistoricalInfo { | ||
pub header: SelfHeader, | ||
} | ||
|
||
#[cfg(test)] | ||
impl From<MockHeader> for AnyConsensusState { | ||
fn from(h: MockHeader) -> Self { | ||
AnyConsensusState::Mock(MockConsensusState(h)) | ||
} | ||
} | ||
|
||
pub trait ChainReader { | ||
fn self_historical_info(&self, height: Height) -> Option<&HistoricalInfo>; | ||
} | ||
|
||
pub trait ChainKeeper { | ||
fn store_historical_info(&mut self, height: Height, info: HistoricalInfo); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
use crate::context::{ChainKeeper, ChainReader, HistoricalInfo, SelfHeader}; | ||
use crate::mock_client::header::MockHeader; | ||
use serde_derive::{Deserialize, Serialize}; | ||
use std::error::Error; | ||
use tendermint::block::Height; | ||
|
||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)] | ||
pub struct MockChainContext { | ||
pub max_size: usize, | ||
pub latest: Height, | ||
pub history: Vec<HistoricalInfo>, | ||
} | ||
|
||
impl MockChainContext { | ||
pub fn new(max_size: usize, n: Height) -> Self { | ||
Self { | ||
max_size, | ||
latest: n, | ||
history: (0..n.value()) | ||
.map(|i| HistoricalInfo { | ||
header: SelfHeader::Mock(MockHeader(Height(i).increment())), | ||
}) | ||
.collect(), | ||
} | ||
} | ||
|
||
pub fn max_size(&self) -> usize { | ||
self.max_size | ||
} | ||
|
||
/// Used for testing | ||
pub fn populate(&mut self, hs: Vec<u64>) { | ||
for h in hs { | ||
self.store_historical_info( | ||
Height(h), | ||
HistoricalInfo { | ||
header: SelfHeader::Mock(MockHeader(Height(h))), | ||
}, | ||
); | ||
} | ||
} | ||
|
||
/// Used for testing | ||
pub fn validate(&self) -> Result<(), Box<dyn Error>> { | ||
// check that the number of entries is not higher than max_size | ||
if self.history.len() > self.max_size { | ||
return Err("too many entries".to_string().into()); | ||
} | ||
|
||
// check latest is properly updated with highest header height | ||
let SelfHeader::Mock(lh) = self.history[self.history.len() - 1].header; | ||
if lh.height() != self.latest { | ||
return Err("latest height is not updated".to_string().into()); | ||
} | ||
|
||
// check that all headers are in sequential order | ||
for i in 1..self.history.len() { | ||
let SelfHeader::Mock(ph) = self.history[i - 1].header; | ||
let SelfHeader::Mock(h) = self.history[i].header; | ||
if ph.height().increment() != h.height() { | ||
return Err("headers in history not sequential".to_string().into()); | ||
} | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl ChainReader for MockChainContext { | ||
fn self_historical_info(&self, height: Height) -> Option<&HistoricalInfo> { | ||
let l = height.value() as usize; | ||
let h = self.latest.value() as usize; | ||
|
||
if l <= h - self.max_size { | ||
// header with height not in the history | ||
None | ||
} else { | ||
Some(&self.history[h - l]) | ||
} | ||
} | ||
} | ||
|
||
impl ChainKeeper for MockChainContext { | ||
fn store_historical_info(&mut self, height: Height, info: HistoricalInfo) { | ||
if height != self.latest.increment() { | ||
return; | ||
} | ||
let mut history = self.history.clone(); | ||
if history.len() >= self.max_size { | ||
history.rotate_left(1); | ||
history[self.max_size - 1] = info; | ||
} else { | ||
history.push(info); | ||
} | ||
//history.insert(height, info); | ||
self.history = history; | ||
self.latest = height; | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::context_mock::MockChainContext; | ||
use tendermint::block::Height; | ||
|
||
#[test] | ||
fn test_store_historical_info() { | ||
pub struct Test { | ||
name: String, | ||
ctx: MockChainContext, | ||
args: Vec<u64>, | ||
} | ||
|
||
impl Test { | ||
pub fn apply(&mut self, hs: Vec<u64>) { | ||
self.ctx.populate(hs); | ||
} | ||
} | ||
|
||
let tests: Vec<Test> = vec![ | ||
Test { | ||
name: "Add no prune".to_string(), | ||
ctx: MockChainContext::new(3, Height(0)), | ||
args: [1].to_vec(), | ||
}, | ||
Test { | ||
name: "Add with prune".to_string(), | ||
ctx: MockChainContext::new(3, Height(2)), | ||
args: [3, 4].to_vec(), | ||
}, | ||
Test { | ||
name: "Attempt to add non sequential headers".to_string(), | ||
ctx: MockChainContext::new(3, Height(2)), | ||
args: [3, 5, 7].to_vec(), | ||
}, | ||
]; | ||
|
||
for mut test in tests { | ||
test.apply(test.args.clone()); | ||
assert!(test.ctx.validate().is_ok()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.