Skip to content

Commit 96387b7

Browse files
committed
Implement IBC client RPCs
1 parent 0633645 commit 96387b7

File tree

12 files changed

+211
-9
lines changed

12 files changed

+211
-9
lines changed

core/src/ibc/client_02/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ pub use self::manager::Manager;
2222
pub use self::types::{ConsensusState, Header, Kind, State, KIND_CODECHAIN};
2323
use crate::ibc;
2424

25-
pub fn new_state(id: &str, ctx: &mut dyn ibc::Context, client_type: Kind) -> Box<dyn State> {
25+
fn new_state(id: &str, ctx: &mut dyn ibc::Context, client_type: Kind) -> Box<dyn State> {
2626
if client_type == KIND_CODECHAIN {
2727
Box::new(codechain::State::new(id, ctx))
2828
} else {
2929
panic!("Invalid client type");
3030
}
3131
}
3232

33-
pub fn get_state(id: &str, ctx: &mut dyn ibc::Context) -> Result<Box<dyn State>, String> {
33+
fn get_state(id: &str, ctx: &mut dyn ibc::Context) -> Result<Box<dyn State>, String> {
3434
let s = codechain::State::find(id);
3535
if s.exists(ctx) {
3636
Ok(Box::new(s))

core/src/ibc/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl<'a> Context for TopLevelContext<'a> {
4343
}
4444
}
4545

46-
pub struct TopLevelKVStore<'a> {
46+
struct TopLevelKVStore<'a> {
4747
state: &'a mut TopLevelState,
4848
}
4949

core/src/ibc/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,16 @@
1414
// You should have received a copy of the GNU Affero General Public License
1515
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616

17-
mod client_02;
17+
pub mod client_02;
1818
#[allow(dead_code)]
1919
#[allow(unused_variables)]
2020
mod commitment_23;
21-
#[allow(dead_code)]
22-
#[allow(unused_variables)]
23-
mod context;
21+
pub mod context;
2422
#[allow(dead_code)]
2523
#[allow(unused_variables)]
2624
pub mod custom_action_handler;
2725
mod kv_store;
2826

27+
pub use self::client_02 as client;
2928
pub use self::context::Context;
3029
pub use self::kv_store::KVStore;

core/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ mod db;
4848
mod db_version;
4949
pub mod encoded;
5050
mod error;
51-
mod ibc;
51+
pub mod ibc;
5252
mod invoice;
5353
mod miner;
5454
mod peer_db;

foundry/rpc_apis.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ impl ApiDependencies {
4848
AccountClient::new(Arc::clone(&self.account_provider), Arc::clone(&self.client), Arc::clone(&self.miner))
4949
.to_delegate(),
5050
);
51+
handler.extend_with(IBCClient::new(Arc::clone(&self.client)).to_delegate())
5152
}
5253
}
5354

rpc/src/v1/errors.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ mod codes {
6464
pub const SHARD_TRANSACTION_ONLY_IN_EXECUTE_TRANSACITON: i64 = -32047;
6565
pub const STATE_NOT_EXIST: i64 = -32048;
6666
pub const ACTION_DATA_HANDLER_NOT_FOUND: i64 = -32049;
67+
pub const IBC_CLIENT_NOT_EXIST: i64 = -32050;
68+
pub const IBC_CLIENT_ROOT_NOT_EXIST: i64 = -32051;
6769
pub const UNKNOWN_ERROR: i64 = -32099;
6870
}
6971

@@ -252,3 +254,19 @@ pub fn io(error: std::io::Error) -> Error {
252254
data: None,
253255
}
254256
}
257+
258+
pub fn ibc_client_not_exist() -> Error {
259+
Error {
260+
code: ErrorCode::ServerError(codes::IBC_CLIENT_NOT_EXIST),
261+
message: "IBC client does not exist".to_string(),
262+
data: None,
263+
}
264+
}
265+
266+
pub fn ibc_client_root_not_exist() -> Error {
267+
Error {
268+
code: ErrorCode::ServerError(codes::IBC_CLIENT_ROOT_NOT_EXIST),
269+
message: "IBC client root does not exist".to_string(),
270+
data: None,
271+
}
272+
}

rpc/src/v1/impls/ibc.rs

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Copyright 2019-2020 Kodebox, Inc.
2+
// This file is part of CodeChain.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
use super::super::errors;
18+
use super::super::traits::IBC;
19+
use super::super::types::IBCQueryResult;
20+
use ccore::ibc;
21+
use ccore::{BlockChainClient, BlockId, StateInfo};
22+
use jsonrpc_core::Result;
23+
use rustc_serialize::hex::ToHex;
24+
use std::sync::Arc;
25+
26+
pub struct IBCClient<C>
27+
where
28+
C: StateInfo + BlockChainClient, {
29+
client: Arc<C>,
30+
}
31+
32+
impl<C> IBCClient<C>
33+
where
34+
C: StateInfo + BlockChainClient,
35+
{
36+
pub fn new(client: Arc<C>) -> Self {
37+
Self {
38+
client,
39+
}
40+
}
41+
}
42+
43+
impl<C> IBC for IBCClient<C>
44+
where
45+
C: StateInfo + 'static + Send + Sync + BlockChainClient,
46+
{
47+
fn query_client_consensus_state(
48+
&self,
49+
client_id: String,
50+
block_number: Option<u64>,
51+
) -> Result<Option<IBCQueryResult>> {
52+
let block_id = block_number.map(BlockId::Number).unwrap_or(BlockId::Latest);
53+
let mut state = self.client.state_at(block_id).ok_or_else(errors::state_not_exist)?;
54+
let block_number = match self.client.block_number(&block_id) {
55+
None => return Ok(None),
56+
Some(block_number) => block_number,
57+
};
58+
59+
let mut context = ibc::context::TopLevelContext::new(&mut state);
60+
let client_manager = ibc::client::Manager::new();
61+
let client_state =
62+
client_manager.query(&mut context, &client_id).map_err(|_| errors::ibc_client_not_exist())?;
63+
64+
let consensus_state = client_state.get_consensus_state(&mut context);
65+
66+
let rlp_encoded_consensus_state = consensus_state.encode();
67+
68+
Ok(Some(IBCQueryResult {
69+
block_number,
70+
raw: rlp_encoded_consensus_state.to_hex(),
71+
// FIXME
72+
proof: "".to_string(),
73+
}))
74+
}
75+
76+
fn query_header(&self, block_number: Option<u64>) -> Result<Option<String>> {
77+
let block_id = block_number.map(BlockId::Number).unwrap_or(BlockId::Latest);
78+
let header = match self.client.block_header(&block_id) {
79+
None => return Ok(None),
80+
Some(header) => header,
81+
};
82+
83+
Ok(Some(header.into_inner().to_hex()))
84+
}
85+
86+
fn query_client_root(
87+
&self,
88+
client_id: String,
89+
other_block_number: u64,
90+
this_block_number: Option<u64>,
91+
) -> Result<Option<IBCQueryResult>> {
92+
let block_id = this_block_number.map(BlockId::Number).unwrap_or(BlockId::Latest);
93+
let mut state = self.client.state_at(block_id).ok_or_else(errors::state_not_exist)?;
94+
let block_number = match self.client.block_number(&block_id) {
95+
None => return Ok(None),
96+
Some(block_number) => block_number,
97+
};
98+
99+
let mut context = ibc::context::TopLevelContext::new(&mut state);
100+
let client_manager = ibc::client::Manager::new();
101+
let client_state =
102+
client_manager.query(&mut context, &client_id).map_err(|_| errors::ibc_client_not_exist())?;
103+
104+
let root =
105+
client_state.get_root(&mut context, other_block_number).map_err(|_| errors::ibc_client_root_not_exist())?;
106+
let rlp_encoded_root = root.encode();
107+
108+
Ok(Some(IBCQueryResult {
109+
block_number,
110+
raw: rlp_encoded_root.to_hex(),
111+
// FIXME
112+
proof: "".to_string(),
113+
}))
114+
}
115+
}

rpc/src/v1/impls/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mod account;
1818
mod chain;
1919
mod devel;
2020
mod engine;
21+
mod ibc;
2122
mod mempool;
2223
mod net;
2324
mod snapshot;
@@ -26,6 +27,7 @@ pub use self::account::AccountClient;
2627
pub use self::chain::ChainClient;
2728
pub use self::devel::DevelClient;
2829
pub use self::engine::EngineClient;
30+
pub use self::ibc::IBCClient;
2931
pub use self::mempool::MempoolClient;
3032
pub use self::net::NetClient;
3133
pub use self::snapshot::SnapshotClient;

rpc/src/v1/traits/ibc.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2019 Kodebox, Inc.
2+
// This file is part of CodeChain.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
use super::super::types::IBCQueryResult;
18+
use jsonrpc_core::Result;
19+
20+
21+
#[rpc(server)]
22+
pub trait IBC {
23+
#[rpc(name = "ibc_query_client_consensus_state")]
24+
fn query_client_consensus_state(
25+
&self,
26+
client_id: String,
27+
block_number: Option<u64>,
28+
) -> Result<Option<IBCQueryResult>>;
29+
30+
#[rpc(name = "ibc_query_header")]
31+
fn query_header(&self, block_number: Option<u64>) -> Result<Option<String>>;
32+
33+
/// Gets the other chain's root saved in the light client
34+
#[rpc(name = "ibc_query_client_root")]
35+
fn query_client_root(
36+
&self,
37+
client_id: String,
38+
other_block_number: u64,
39+
this_block_number: Option<u64>,
40+
) -> Result<Option<IBCQueryResult>>;
41+
}

rpc/src/v1/traits/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mod account;
1818
mod chain;
1919
mod devel;
2020
mod engine;
21+
mod ibc;
2122
mod mempool;
2223
mod net;
2324
mod snapshot;
@@ -26,6 +27,7 @@ pub use self::account::Account;
2627
pub use self::chain::Chain;
2728
pub use self::devel::Devel;
2829
pub use self::engine::Engine;
30+
pub use self::ibc::IBC;
2931
pub use self::mempool::Mempool;
3032
pub use self::net::Net;
3133
pub use self::snapshot::Snapshot;

0 commit comments

Comments
 (0)