Skip to content

Commit 4d700d3

Browse files
committed
Add RPC snapshot_getList
1 parent 96739f9 commit 4d700d3

10 files changed

Lines changed: 143 additions & 1 deletion

File tree

codechain/rpc_apis.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ impl ApiDependencies {
3535
use crpc::v1::*;
3636
handler.extend_with(ChainClient::new(Arc::clone(&self.client)).to_delegate());
3737
handler.extend_with(MempoolClient::new(Arc::clone(&self.client)).to_delegate());
38+
handler.extend_with(SnapshotClient::new(Arc::clone(&self.client)).to_delegate());
3839
if enable_devel_api {
3940
handler.extend_with(
4041
DevelClient::new(Arc::clone(&self.client), Arc::clone(&self.miner), self.block_sync.clone())

codechain/run_node.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,9 @@ pub fn run_node(matches: &ArgMatches) -> Result<(), String> {
272272
let ap = prepare_account_provider(&keys_path)?;
273273
unlock_accounts(&*ap, &pf)?;
274274

275-
let client_config: ClientConfig = Default::default();
275+
let mut client_config: ClientConfig = Default::default();
276+
client_config.snapshot_dir = config.snapshot.path.clone();
277+
276278
let db = open_db(&config.operating, &client_config)?;
277279

278280
let miner = new_miner(&config, &scheme, ap.clone(), Arc::clone(&db))?;

core/src/client/client.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ pub struct Client {
8181

8282
/// Timer for reseal_min_period/reseal_max_period on miner client
8383
reseal_timer: TimerApi,
84+
85+
/// Root directory for sync snapshots
86+
snapshot_dir: Option<String>,
8487
}
8588

8689
impl Client {
@@ -125,6 +128,7 @@ impl Client {
125128
genesis_accounts,
126129
importer,
127130
reseal_timer,
131+
snapshot_dir: config.snapshot_dir.clone(),
128132
});
129133

130134
// ensure buffered changes are flushed.
@@ -955,4 +959,8 @@ impl SnapshotClient for Client {
955959
self.engine.send_snapshot_notify(header.hash())
956960
}
957961
}
962+
963+
fn snapshot_dir(&self) -> Option<&String> {
964+
self.snapshot_dir.as_ref()
965+
}
958966
}

core/src/client/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ pub struct ClientConfig {
7777
pub state_cache_size: usize,
7878
/// Type of block verifier used by client.
7979
pub verifier_type: VerifierType,
80+
/// Root directory for sync snapshots
81+
pub snapshot_dir: Option<String>,
8082
}
8183

8284
impl Default for ClientConfig {
@@ -90,6 +92,7 @@ impl Default for ClientConfig {
9092
db_wal: true,
9193
state_cache_size: DEFAULT_STATE_CACHE_SIZE as usize * mb,
9294
verifier_type: Default::default(),
95+
snapshot_dir: None,
9396
}
9497
}
9598
}

core/src/client/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,4 +350,5 @@ pub trait StateInfo {
350350

351351
pub trait SnapshotClient {
352352
fn notify_snapshot(&self, id: BlockId);
353+
fn snapshot_dir(&self) -> Option<&String>;
353354
}

rpc/src/v1/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,14 @@ pub fn invalid_custom_action(err: String) -> Error {
304304
}
305305
}
306306

307+
pub fn io(error: std::io::Error) -> Error {
308+
Error {
309+
code: ErrorCode::InternalError,
310+
message: format!("{}", error),
311+
data: None,
312+
}
313+
}
314+
307315
/// Internal error signifying a logic error in code.
308316
/// Should not be used when function can just fail
309317
/// because of invalid parameters or incomplete node state.

rpc/src/v1/impls/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ mod engine;
2121
mod mempool;
2222
mod miner;
2323
mod net;
24+
mod snapshot;
2425

2526
pub use self::account::AccountClient;
2627
pub use self::chain::ChainClient;
@@ -29,3 +30,4 @@ pub use self::engine::EngineClient;
2930
pub use self::mempool::MempoolClient;
3031
pub use self::miner::MinerClient;
3132
pub use self::net::NetClient;
33+
pub use self::snapshot::SnapshotClient;

rpc/src/v1/impls/snapshot.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright 2018-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 std::fs;
18+
use std::str::FromStr;
19+
use std::sync::Arc;
20+
21+
use ccore::{BlockChainClient, BlockId, SnapshotClient as CoreSnapshotClient};
22+
use ctypes::BlockHash;
23+
use primitives::H256;
24+
25+
use jsonrpc_core::Result;
26+
27+
use super::super::errors;
28+
use super::super::traits::Snapshot;
29+
use super::super::types::BlockNumberAndHash;
30+
31+
pub struct SnapshotClient<C>
32+
where
33+
C: BlockChainClient + CoreSnapshotClient, {
34+
client: Arc<C>,
35+
}
36+
37+
impl<C> SnapshotClient<C>
38+
where
39+
C: BlockChainClient + CoreSnapshotClient,
40+
{
41+
pub fn new(client: Arc<C>) -> Self {
42+
SnapshotClient {
43+
client,
44+
}
45+
}
46+
}
47+
48+
impl<C> Snapshot for SnapshotClient<C>
49+
where
50+
C: BlockChainClient + CoreSnapshotClient + 'static,
51+
{
52+
fn get_snapshot_list(&self) -> Result<Vec<BlockNumberAndHash>> {
53+
let ids = {
54+
if let Some(snapshot_dir) = self.client.snapshot_dir() {
55+
let mut result = Vec::new();
56+
for entry in fs::read_dir(snapshot_dir).map_err(errors::io)? {
57+
let entry = entry.map_err(errors::io)?;
58+
59+
// Check if the entry is a directory
60+
let file_type = entry.file_type().map_err(errors::io)?;
61+
if !file_type.is_dir() {
62+
continue
63+
}
64+
65+
let path = entry.path();
66+
let name = match path.file_name().expect("Directories always have file name").to_str() {
67+
Some(n) => n,
68+
None => continue,
69+
};
70+
let hash = match H256::from_str(name) {
71+
Ok(h) => BlockHash::from(h),
72+
Err(_) => continue,
73+
};
74+
if let Some(number) = self.client.block_number(&BlockId::Hash(hash)) {
75+
result.push(BlockNumberAndHash {
76+
number,
77+
hash,
78+
});
79+
}
80+
}
81+
result.sort_unstable_by(|a, b| b.number.cmp(&a.number));
82+
result
83+
} else {
84+
Vec::new()
85+
}
86+
};
87+
Ok(ids)
88+
}
89+
}

rpc/src/v1/traits/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ mod engine;
2121
mod mempool;
2222
mod miner;
2323
mod net;
24+
mod snapshot;
2425

2526
pub use self::account::Account;
2627
pub use self::chain::Chain;
@@ -29,3 +30,4 @@ pub use self::engine::Engine;
2930
pub use self::mempool::Mempool;
3031
pub use self::miner::Miner;
3132
pub use self::net::Net;
33+
pub use self::snapshot::Snapshot;

rpc/src/v1/traits/snapshot.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2018-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 jsonrpc_core::Result;
18+
19+
use super::super::types::BlockNumberAndHash;
20+
21+
#[rpc(server)]
22+
pub trait Snapshot {
23+
/// Gets list of block numbers and block hashes of the snapshots.
24+
#[rpc(name = "snapshot_getList")]
25+
fn get_snapshot_list(&self) -> Result<Vec<BlockNumberAndHash>>;
26+
}

0 commit comments

Comments
 (0)