Skip to content

Commit

Permalink
config: make rpc api configurable (#1750)
Browse files Browse the repository at this point in the history
* config: make rpc api configurable

* fix typo
  • Loading branch information
nanne007 authored Dec 3, 2020
1 parent 72b7569 commit 2433156
Show file tree
Hide file tree
Showing 7 changed files with 500 additions and 145 deletions.
216 changes: 216 additions & 0 deletions config/src/api_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
use serde::de::Error;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::collections::HashSet;
use std::str::FromStr;

#[derive(Debug, PartialEq, Ord, PartialOrd, Clone, Copy, Eq, Hash)]
pub enum Api {
Account,
Chain,
Debug,
Dev,
Miner,
NetworkManager,
NodeManager,
Node,
PubSub,
State,
SyncManager,
TxPool,
}
impl Serialize for Api {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
self.to_string().serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Api {
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
let s = <String>::deserialize(deserializer)?;
Api::from_str(&s).map_err(D::Error::custom)
}
}

impl std::fmt::Display for Api {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let display = match self {
Self::Account => "account",
Self::Chain => "chain",
Self::Debug => "debug",
Self::Dev => "dev",
Self::Miner => "miner",
Self::NetworkManager => "network_manager",
Self::NodeManager => "node_manager",
Self::Node => "node",
Self::PubSub => "pubsub",
Self::State => "state",
Self::SyncManager => "sync_manager",
Self::TxPool => "txpool",
};
write!(f, "{}", display)
}
}

impl FromStr for Api {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
use self::Api::*;

match s {
"account" => Ok(Account),
"chain" => Ok(Chain),
"debug" => Ok(Debug),
"dev" => Ok(Dev),
"miner" => Ok(Miner),
"network_manager" => Ok(NetworkManager),
"node_manager" => Ok(NodeManager),
"node" => Ok(Node),
"pubsub" => Ok(PubSub),
"state" => Ok(State),
"sync_manager" => Ok(SyncManager),
"txpool" => Ok(TxPool),
api => Err(format!("Unknown api: {}", api)),
}
}
}

#[derive(Debug, Clone)]
pub enum ApiSet {
// Unsafe context (like jsonrpc over http)
UnsafeContext,
// All possible APIs (safe context like token-protected WS interface)
All,
// Local "unsafe" context and accounts access
IpcContext,
// APIs for Generic Pub-Sub
PubSub,
// Fixed list of APis
List(HashSet<Api>),
}

impl Default for ApiSet {
fn default() -> Self {
ApiSet::UnsafeContext
}
}

impl PartialEq for ApiSet {
fn eq(&self, other: &Self) -> bool {
self.list_apis() == other.list_apis()
}
}

impl std::fmt::Display for ApiSet {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut apis: Vec<_> = self.list_apis().into_iter().collect();
apis.sort();
let mut iter = apis.iter();
let first = iter.next();
let display = iter.fold(
first.map(ToString::to_string).unwrap_or_default(),
|mut a, b| {
a.push(',');
a.push_str(&b.to_string());
a
},
);
write!(f, "{}", display)
}
}

impl FromStr for ApiSet {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut apis = HashSet::new();

for api in s.split(',') {
match api {
"all" => {
apis.extend(ApiSet::All.list_apis());
}
"safe" => {
// Safe APIs are those that are safe even in UnsafeContext.
apis.extend(ApiSet::UnsafeContext.list_apis());
}
"ipc" => {
apis.extend(ApiSet::IpcContext.list_apis());
}
"pubsub" => {
apis.extend(ApiSet::PubSub.list_apis());
}
// Remove the API
api if api.starts_with('-') => {
let api = api[1..].parse()?;
apis.remove(&api);
}
api => {
let api = api.parse()?;
apis.insert(api);
}
}
}

Ok(ApiSet::List(apis))
}
}

impl Serialize for ApiSet {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
self.to_string().serialize(serializer)
}
}
impl<'de> Deserialize<'de> for ApiSet {
fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
let s = <String>::deserialize(deserializer)?;
ApiSet::from_str(&s).map_err(D::Error::custom)
}
}

impl ApiSet {
pub fn list_apis(&self) -> HashSet<Api> {
let mut public_list: HashSet<Api> = [
Api::Chain,
Api::Dev,
Api::Miner,
Api::Node,
Api::State,
Api::TxPool,
]
.iter()
.cloned()
.collect();

match *self {
ApiSet::UnsafeContext => public_list,
ApiSet::List(ref apis) => apis.iter().cloned().collect(),

ApiSet::IpcContext | ApiSet::All => {
public_list.insert(Api::PubSub);
public_list.insert(Api::Debug);
public_list.insert(Api::Account);
public_list.insert(Api::NetworkManager);
public_list.insert(Api::SyncManager);
public_list.insert(Api::NodeManager);
public_list
}

ApiSet::PubSub => {
public_list.insert(Api::PubSub);
public_list
}
}
}
}
17 changes: 15 additions & 2 deletions config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use std::sync::Arc;
use structopt::StructOpt;

mod account_vault_config;
mod api_config;
mod available_port;
mod logger_config;
mod metrics_config;
Expand All @@ -34,10 +35,11 @@ mod storage_config;
mod sync_config;
mod txpool_config;

use crate::rpc_config::{HttpConfiguration, IpcConfiguration, TcpConfiguration, WsConfiguration};
pub use api_config::{Api, ApiSet};
pub use available_port::{
get_available_port_from, get_random_available_port, get_random_available_ports,
};

pub use libra_temppath::TempPath;
pub use logger_config::LoggerConfig;
pub use metrics_config::MetricsConfig;
Expand Down Expand Up @@ -186,6 +188,15 @@ pub struct StarcoinOpt {
/// Init chain by a custom genesis config. if want to reuse builtin network config, just pass a builtin network name.
/// This option only work for node init start.
pub genesis_config: Option<String>,

#[structopt(flatten)]
pub http: HttpConfiguration,
#[structopt(flatten)]
pub tcp: TcpConfiguration,
#[structopt(flatten)]
pub ws: WsConfiguration,
#[structopt(flatten)]
pub ipc: IpcConfiguration,
}

#[derive(Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -429,7 +440,9 @@ where
T: Serialize + DeserializeOwned,
P: AsRef<Path>,
{
let contents = toml::to_vec(c)?;
// fix toml table problem, see https://github.com/alexcrichton/toml-rs/issues/142
let c = toml::value::Value::try_from(c)?;
let contents = toml::to_vec(&c)?;
let mut file = File::create(output_file)?;
file.write_all(&contents)?;
Ok(())
Expand Down
Loading

0 comments on commit 2433156

Please sign in to comment.