Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit b47b183

Browse files
committed
Parity as a library
1 parent db7a8c4 commit b47b183

File tree

12 files changed

+618
-320
lines changed

12 files changed

+618
-320
lines changed

Cargo.lock

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ ethcore-miner = { path = "miner" }
4141
ethcore-network = { path = "util/network" }
4242
ethcore-private-tx = { path = "ethcore/private-tx" }
4343
ethcore-service = { path = "ethcore/service" }
44-
ethcore-stratum = { path = "ethcore/stratum" }
4544
ethcore-sync = { path = "ethcore/sync" }
4645
ethcore-transaction = { path = "ethcore/transaction" }
4746
ethereum-types = "0.3"
@@ -109,6 +108,9 @@ slow-blocks = ["ethcore/slow-blocks"]
109108
secretstore = ["ethcore-secretstore"]
110109
final = ["parity-version/final"]
111110

111+
[lib]
112+
path = "parity/lib.rs"
113+
112114
[[bin]]
113115
path = "parity/main.rs"
114116
name = "parity"
@@ -131,6 +133,7 @@ members = [
131133
"ethstore/cli",
132134
"evmbin",
133135
"miner",
136+
"parity-clib",
134137
"transaction-pool",
135138
"whisper",
136139
"whisper/cli",

parity-clib/Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
description = "C bindings for the Parity Ethereum client"
3+
name = "parity-clib"
4+
version = "1.11.0"
5+
license = "GPL-3.0"
6+
authors = ["Parity Technologies <[email protected]>"]
7+
8+
[lib]
9+
name = "parity"
10+
crate-type = ["cdylib", "staticlib"]
11+
12+
[dependencies]
13+
parity = { path = "../", default-features = false }
14+
15+
[features]
16+
default = []
17+
final = ["parity/final"]

parity-clib/parity.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright 2018 Parity Technologies (UK) Ltd.
2+
// This file is part of Parity.
3+
4+
// Parity is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// Parity 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 General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
16+
17+
#ifndef _PARITY_H_INCLUDED_
18+
#define _PARITY_H_INCLUDED_
19+
20+
#include <cstddef>
21+
22+
/// Parameters to pass to `parity_start`.
23+
struct ParityParams {
24+
/// Configuration object, as handled by the `parity_config_*` functions.
25+
/// Note that calling `parity_start` will destroy the configuration object (even on failure).
26+
void *configuration;
27+
28+
/// Callback function to call when the client receives an RPC request to change its chain spec.
29+
///
30+
/// The second and third parameters of the callback are the string pointer and length.
31+
void (*on_client_restart_cb)(void *, const char *, size_t);
32+
33+
/// Custom parameter passed to the `on_client_restart_cb` callback as first parameter.
34+
void *on_client_restart_cb_custom;
35+
};
36+
37+
#ifdef __cplusplus
38+
extern "C" {
39+
#endif
40+
41+
/// Builds a new configuration object by parsing a list of CLI arguments.
42+
///
43+
/// The first two parameters are string pointers and string lengths. They must have a length equal
44+
/// to `len`. The strings don't need to be zero-terminated.
45+
///
46+
/// Returns 0 on success, and non-zero on error.
47+
///
48+
/// # Example
49+
///
50+
/// ```no_run
51+
/// void* cfg;
52+
/// const char *args[] = {"--light"};
53+
/// size_t str_lens[] = {7};
54+
/// if (parity_config_from_cli(args, str_lens, 1, &cfg) != 0) {
55+
/// return 1;
56+
/// }
57+
/// ```
58+
///
59+
int parity_config_from_cli(char const *const *args, size_t const *arg_lens, size_t len, void **out);
60+
61+
/// Destroys a configuration object created earlier.
62+
///
63+
/// **Important**: You probably don't need to call this function. Calling `parity_start` destroys
64+
/// the configuration object as well (even on failure).
65+
void parity_config_destroy(void *);
66+
67+
/// Starts the parity client in background threads. Returns a pointer to a struct that represents
68+
/// the running client.
69+
///
70+
/// **Important**: The configuration object passed inside `cfg` is destroyed when you
71+
/// call `parity_start` (even on failure).
72+
///
73+
/// Returns 0 on success, and non-zero on error.
74+
int parity_start(const ParityParams *, void **);
75+
76+
/// Destroys the parity client created with `parity_start`.
77+
void parity_destroy(void *);
78+
79+
#ifdef __cplusplus
80+
}
81+
#endif
82+
83+
#endif // include guard

parity-clib/src/lib.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// Copyright 2018 Parity Technologies (UK) Ltd.
2+
// This file is part of Parity.
3+
4+
// Parity is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// Parity 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 General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
16+
17+
//! Note that all the structs and functions here are documented in `parity.h`, to avoid
18+
//! duplicating documentation.
19+
20+
extern crate parity;
21+
22+
use std::os::raw::{c_char, c_void, c_int};
23+
use std::panic;
24+
use std::ptr;
25+
use std::slice;
26+
27+
#[repr(C)]
28+
pub struct ParityParams {
29+
pub configuration: *mut c_void,
30+
pub on_client_restart_cb: extern "C" fn(*mut c_void, *const c_char, usize),
31+
pub on_client_restart_cb_custom: *mut c_void,
32+
}
33+
34+
#[no_mangle]
35+
pub extern fn parity_config_from_cli(args: *const *const c_char, args_lens: *const usize, len: usize, output: *mut *mut c_void) -> c_int {
36+
unsafe {
37+
panic::catch_unwind(|| {
38+
*output = ptr::null_mut();
39+
40+
let args = {
41+
let arg_ptrs = slice::from_raw_parts(args, len);
42+
let arg_lens = slice::from_raw_parts(args_lens, len);
43+
44+
let mut args = Vec::with_capacity(len + 1);
45+
args.push("parity".to_owned());
46+
47+
for (&arg, &len) in arg_ptrs.iter().zip(arg_lens.iter()) {
48+
let string = slice::from_raw_parts(arg as *const u8, len);
49+
match String::from_utf8(string.to_owned()) {
50+
Ok(a) => args.push(a),
51+
Err(_) => return 1,
52+
};
53+
}
54+
55+
args
56+
};
57+
58+
match parity::Configuration::parse_cli(&args) {
59+
Ok(mut cfg) => {
60+
// Always disable the auto-updater when used as a library.
61+
cfg.args.arg_auto_update = "none".to_owned();
62+
63+
let cfg = Box::into_raw(Box::new(cfg));
64+
*output = cfg as *mut _;
65+
0
66+
},
67+
Err(_) => {
68+
1
69+
},
70+
}
71+
}).unwrap_or(1)
72+
}
73+
}
74+
75+
#[no_mangle]
76+
pub extern fn parity_config_destroy(cfg: *mut c_void) {
77+
unsafe {
78+
let _ = panic::catch_unwind(|| {
79+
let _cfg = Box::from_raw(cfg as *mut parity::Configuration);
80+
});
81+
}
82+
}
83+
84+
#[no_mangle]
85+
pub extern fn parity_start(cfg: *const ParityParams, output: *mut *mut c_void) -> c_int {
86+
unsafe {
87+
panic::catch_unwind(|| {
88+
*output = ptr::null_mut();
89+
let cfg: &ParityParams = &*cfg;
90+
91+
let config = Box::from_raw(cfg.configuration as *mut parity::Configuration);
92+
93+
let on_client_restart_cb = {
94+
struct Cb(extern "C" fn(*mut c_void, *const c_char, usize), *mut c_void);
95+
unsafe impl Send for Cb {}
96+
unsafe impl Sync for Cb {}
97+
impl Cb {
98+
fn call(&self, new_chain: String) {
99+
let cb = self.0;
100+
cb(self.1, new_chain.as_bytes().as_ptr() as *const _, new_chain.len())
101+
}
102+
}
103+
let cb = Cb(cfg.on_client_restart_cb, cfg.on_client_restart_cb_custom);
104+
move |new_chain: String| { cb.call(new_chain); }
105+
};
106+
107+
let action = match parity::start(*config, on_client_restart_cb, || {}) {
108+
Ok(action) => action,
109+
Err(_) => return 1,
110+
};
111+
112+
match action {
113+
parity::ExecutionAction::Instant(Some(s)) => { println!("{}", s); 0 },
114+
parity::ExecutionAction::Instant(None) => 0,
115+
parity::ExecutionAction::Running(client) => {
116+
*output = Box::into_raw(Box::<parity::RunningClient>::new(client)) as *mut c_void;
117+
0
118+
}
119+
}
120+
}).unwrap_or(1)
121+
}
122+
}
123+
124+
#[no_mangle]
125+
pub extern fn parity_destroy(client: *mut c_void) {
126+
unsafe {
127+
let _ = panic::catch_unwind(|| {
128+
let client = Box::from_raw(client as *mut parity::RunningClient);
129+
client.shutdown();
130+
});
131+
}
132+
}

parity/blockchain.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ use params::{SpecType, Pruning, Switch, tracing_switch_to_bool, fatdb_switch_to_
3737
use helpers::{to_client_config, execute_upgrades};
3838
use dir::Directories;
3939
use user_defaults::UserDefaults;
40-
use fdlimit;
4140
use ethcore_private_tx;
4241
use db;
4342

@@ -178,8 +177,6 @@ fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> {
178177
// load user defaults
179178
let user_defaults = UserDefaults::load(&user_defaults_path)?;
180179

181-
fdlimit::raise_fd_limit();
182-
183180
// select pruning algorithm
184181
let algorithm = cmd.pruning.to_algorithm(&user_defaults);
185182

@@ -327,8 +324,6 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> {
327324
// load user defaults
328325
let mut user_defaults = UserDefaults::load(&user_defaults_path)?;
329326

330-
fdlimit::raise_fd_limit();
331-
332327
// select pruning algorithm
333328
let algorithm = cmd.pruning.to_algorithm(&user_defaults);
334329

@@ -518,8 +513,6 @@ fn start_client(
518513
// load user defaults
519514
let user_defaults = UserDefaults::load(&user_defaults_path)?;
520515

521-
fdlimit::raise_fd_limit();
522-
523516
// select pruning algorithm
524517
let algorithm = pruning.to_algorithm(&user_defaults);
525518

parity/cli/usage.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ macro_rules! usage {
198198
}
199199
}
200200

201+
/// Parsed command line arguments.
201202
#[derive(Debug, PartialEq)]
202203
pub struct Args {
203204
$(

parity/configuration.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,30 @@ pub struct Execute {
9292
pub cmd: Cmd,
9393
}
9494

95+
/// Configuration for the Parity client.
9596
#[derive(Debug, PartialEq)]
9697
pub struct Configuration {
98+
/// Arguments to be interpreted.
9799
pub args: Args,
98100
}
99101

100102
impl Configuration {
101-
pub fn parse<S: AsRef<str>>(command: &[S]) -> Result<Self, ArgsError> {
102-
let args = Args::parse(command)?;
103-
103+
/// Parses a configuration from a list of command line arguments.
104+
///
105+
/// # Example
106+
///
107+
/// ```
108+
/// let _cfg = parity::Configuration::parse_cli(&["--light", "--chain", "koven"]).unwrap();
109+
/// ```
110+
pub fn parse_cli<S: AsRef<str>>(command: &[S]) -> Result<Self, ArgsError> {
104111
let config = Configuration {
105-
args: args,
112+
args: Args::parse(command)?,
106113
};
107114

108115
Ok(config)
109116
}
110117

111-
pub fn into_command(self) -> Result<Execute, String> {
118+
pub(crate) fn into_command(self) -> Result<Execute, String> {
112119
let dirs = self.directories();
113120
let pruning = self.args.arg_pruning.parse()?;
114121
let pruning_history = self.args.arg_pruning_history;

0 commit comments

Comments
 (0)