Expose all other RPCs.

This commit is contained in:
Gav Wood 2016-12-12 02:57:19 +01:00
parent 2d0d4682ad
commit 758744449f
No known key found for this signature in database
GPG Key ID: C49C1ACA1CC9B252
12 changed files with 215 additions and 18 deletions

1
Cargo.lock generated
View File

@ -524,6 +524,7 @@ dependencies = [
"parity-updater 1.5.0", "parity-updater 1.5.0",
"rlp 0.1.0", "rlp 0.1.0",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -315,4 +315,29 @@ export default class Parity {
.execute('parity_unsignedTransactionsCount') .execute('parity_unsignedTransactionsCount')
.then(outNumber); .then(outNumber);
} }
consensusCapability () {
return this._transport
.execute('parity_consensusCapability')
}
versionInfo () {
return this._transport
.execute('parity_versionInfo')
}
releasesInfo () {
return this._transport
.execute('parity_releasesInfo')
}
upgradeReady () {
return this._transport
.execute('parity_upgradeReady')
}
executeUpgrade () {
return this._transport
.execute('parity_executeUpgrade')
}
} }

View File

@ -242,7 +242,7 @@ pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet
server.add_delegate(ParityAccountsClient::new(&deps.secret_store, &deps.client).to_delegate()); server.add_delegate(ParityAccountsClient::new(&deps.secret_store, &deps.client).to_delegate());
}, },
Api::ParitySet => { Api::ParitySet => {
server.add_delegate(ParitySetClient::new(&deps.client, &deps.miner, &deps.net_service).to_delegate()) server.add_delegate(ParitySetClient::new(&deps.client, &deps.miner, &deps.updater, &deps.net_service).to_delegate())
}, },
Api::Traces => { Api::Traces => {
server.add_delegate(TracesClient::new(&deps.client, &deps.miner).to_delegate()) server.add_delegate(TracesClient::new(&deps.client, &deps.miner).to_delegate())

View File

@ -34,6 +34,7 @@ serde_macros = { version = "0.8.0", optional = true }
clippy = { version = "0.0.103", optional = true} clippy = { version = "0.0.103", optional = true}
ethcore-ipc = { path = "../ipc/rpc" } ethcore-ipc = { path = "../ipc/rpc" }
time = "0.1" time = "0.1"
semver = "0.5"
[build-dependencies] [build-dependencies]
serde_codegen = { version = "0.8.0", optional = true } serde_codegen = { version = "0.8.0", optional = true }

View File

@ -19,6 +19,7 @@
#![cfg_attr(feature="nightly", feature(custom_derive, custom_attribute, plugin))] #![cfg_attr(feature="nightly", feature(custom_derive, custom_attribute, plugin))]
#![cfg_attr(feature="nightly", plugin(serde_macros, clippy))] #![cfg_attr(feature="nightly", plugin(serde_macros, clippy))]
extern crate semver;
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;

View File

@ -38,7 +38,8 @@ use v1::types::{
Bytes, U256, H160, H256, H512, Bytes, U256, H160, H256, H512,
Peers, Transaction, RpcSettings, Histogram, Peers, Transaction, RpcSettings, Histogram,
TransactionStats, LocalTransactionStatus, TransactionStats, LocalTransactionStatus,
BlockNumber, ConsensusCapability BlockNumber, ConsensusCapability, VersionInfo,
OperationsInfo
}; };
use v1::helpers::{errors, SigningQueue, SignerService, NetworkSettings}; use v1::helpers::{errors, SigningQueue, SignerService, NetworkSettings};
use v1::helpers::dispatch::DEFAULT_MAC; use v1::helpers::dispatch::DEFAULT_MAC;
@ -366,4 +367,16 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
let updater = take_weak!(self.updater); let updater = take_weak!(self.updater);
Ok(updater.capability().into()) Ok(updater.capability().into())
} }
fn version_info(&self) -> Result<VersionInfo, Error> {
try!(self.active());
let updater = take_weak!(self.updater);
Ok(updater.version_info().into())
}
fn releases_info(&self) -> Result<Option<OperationsInfo>, Error> {
try!(self.active());
let updater = take_weak!(self.updater);
Ok(updater.info().map(Into::into))
}
} }

View File

@ -24,45 +24,51 @@ use ethcore::mode::Mode;
use ethsync::ManageNetwork; use ethsync::ManageNetwork;
use fetch::{Client as FetchClient, Fetch}; use fetch::{Client as FetchClient, Fetch};
use util::{Mutex, sha3}; use util::{Mutex, sha3};
use updater::{Service as UpdateService};
use jsonrpc_core::Error; use jsonrpc_core::Error;
use v1::helpers::auto_args::Ready; use v1::helpers::auto_args::Ready;
use v1::helpers::errors; use v1::helpers::errors;
use v1::traits::ParitySet; use v1::traits::ParitySet;
use v1::types::{Bytes, H160, H256, U256}; use v1::types::{Bytes, H160, H256, U256, ReleaseInfo};
/// Parity-specific rpc interface for operations altering the settings. /// Parity-specific rpc interface for operations altering the settings.
pub struct ParitySetClient<C, M, F=FetchClient> where pub struct ParitySetClient<C, M, U, F=FetchClient> where
C: MiningBlockChainClient, C: MiningBlockChainClient,
M: MinerService, M: MinerService,
U: UpdateService,
F: Fetch, F: Fetch,
{ {
client: Weak<C>, client: Weak<C>,
miner: Weak<M>, miner: Weak<M>,
updater: Weak<U>,
net: Weak<ManageNetwork>, net: Weak<ManageNetwork>,
fetch: Mutex<F>, fetch: Mutex<F>,
} }
impl<C, M> ParitySetClient<C, M, FetchClient> where impl<C, M, U> ParitySetClient<C, M, U, FetchClient> where
C: MiningBlockChainClient, C: MiningBlockChainClient,
M: MinerService M: MinerService,
U: UpdateService,
{ {
/// Creates new `ParitySetClient` with default `FetchClient`. /// Creates new `ParitySetClient` with default `FetchClient`.
pub fn new(client: &Arc<C>, miner: &Arc<M>, net: &Arc<ManageNetwork>) -> Self { pub fn new(client: &Arc<C>, miner: &Arc<M>, updater: &Arc<U>, net: &Arc<ManageNetwork>) -> Self {
Self::with_fetch(client, miner, net) Self::with_fetch(client, miner, updater, net)
} }
} }
impl<C, M, F> ParitySetClient<C, M, F> where impl<C, M, U, F> ParitySetClient<C, M, U, F> where
C: MiningBlockChainClient, C: MiningBlockChainClient,
M: MinerService, M: MinerService,
U: UpdateService,
F: Fetch, F: Fetch,
{ {
/// Creates new `ParitySetClient` with default `FetchClient`. /// Creates new `ParitySetClient` with default `FetchClient`.
pub fn with_fetch(client: &Arc<C>, miner: &Arc<M>, net: &Arc<ManageNetwork>) -> Self { pub fn with_fetch(client: &Arc<C>, miner: &Arc<M>, updater: &Arc<U>, net: &Arc<ManageNetwork>) -> Self {
ParitySetClient { ParitySetClient {
client: Arc::downgrade(client), client: Arc::downgrade(client),
miner: Arc::downgrade(miner), miner: Arc::downgrade(miner),
updater: Arc::downgrade(updater),
net: Arc::downgrade(net), net: Arc::downgrade(net),
fetch: Mutex::new(F::default()), fetch: Mutex::new(F::default()),
} }
@ -75,9 +81,10 @@ impl<C, M, F> ParitySetClient<C, M, F> where
} }
} }
impl<C, M, F> ParitySet for ParitySetClient<C, M, F> where impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
C: MiningBlockChainClient + 'static, C: MiningBlockChainClient + 'static,
M: MinerService + 'static, M: MinerService + 'static,
U: UpdateService + 'static,
F: Fetch + 'static, F: Fetch + 'static,
{ {
@ -230,4 +237,16 @@ impl<C, M, F> ParitySet for ParitySetClient<C, M, F> where
} }
} }
} }
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>, Error> {
try!(self.active());
let updater = take_weak!(self.updater);
Ok(updater.upgrade_ready().map(Into::into))
}
fn execute_upgrade(&self) -> Result<bool, Error> {
try!(self.active());
let updater = take_weak!(self.updater);
Ok(updater.execute_upgrade())
}
} }

View File

@ -23,7 +23,8 @@ use v1::types::{
H160, H256, H512, U256, Bytes, H160, H256, H512, U256, Bytes,
Peers, Transaction, RpcSettings, Histogram, Peers, Transaction, RpcSettings, Histogram,
TransactionStats, LocalTransactionStatus, TransactionStats, LocalTransactionStatus,
BlockNumber, ConsensusCapability BlockNumber, ConsensusCapability, VersionInfo,
OperationsInfo
}; };
build_rpc_trait! { build_rpc_trait! {
@ -159,5 +160,13 @@ build_rpc_trait! {
/// Returns information on current consensus capability. /// Returns information on current consensus capability.
#[rpc(name = "parity_consensusCapability")] #[rpc(name = "parity_consensusCapability")]
fn consensus_capability(&self) -> Result<ConsensusCapability, Error>; fn consensus_capability(&self) -> Result<ConsensusCapability, Error>;
/// Get our version information in a nice object.
#[rpc(name = "parity_versionInfo")]
fn version_info(&self) -> Result<VersionInfo, Error>;
/// Get information concerning the latest releases if available.
#[rpc(name = "parity_releasesInfo")]
fn releases_info(&self) -> Result<Option<OperationsInfo>, Error>;
} }
} }

View File

@ -19,7 +19,7 @@
use jsonrpc_core::Error; use jsonrpc_core::Error;
use v1::helpers::auto_args::{Wrap, WrapAsync, Ready}; use v1::helpers::auto_args::{Wrap, WrapAsync, Ready};
use v1::types::{Bytes, H160, H256, U256}; use v1::types::{Bytes, H160, H256, U256, ReleaseInfo};
build_rpc_trait! { build_rpc_trait! {
/// Parity-specific rpc interface for operations altering the settings. /// Parity-specific rpc interface for operations altering the settings.
@ -91,5 +91,13 @@ build_rpc_trait! {
/// Hash a file content under given URL. /// Hash a file content under given URL.
#[rpc(async, name = "parity_hashContent")] #[rpc(async, name = "parity_hashContent")]
fn hash_content(&self, Ready<H256>, String); fn hash_content(&self, Ready<H256>, String);
/// Is there a release ready for install?
#[rpc(name = "parity_upgradeReady")]
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>, Error>;
/// Execute a release which is ready according to upgrade_ready().
#[rpc(name = "parity_executeUpgrade")]
fn execute_upgrade(&self) -> Result<bool, Error>;
} }
} }

View File

@ -14,10 +14,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use updater::CapState; use semver;
use v1::types::{H160, H256};
use updater::{self, CapState};
/// Capability info /// Capability info
#[derive(Debug, Serialize, PartialEq)] #[derive(Debug, PartialEq, Serialize)]
pub enum ConsensusCapability { pub enum ConsensusCapability {
/// Unknown. /// Unknown.
#[serde(rename="unknown")] #[serde(rename="unknown")]
@ -44,3 +46,116 @@ impl Into<ConsensusCapability> for CapState {
} }
} }
/// A release's track.
#[derive(Debug, PartialEq, Serialize)]
pub enum ReleaseTrack {
/// Stable track.
Stable,
/// Beta track.
Beta,
/// Nightly track.
Nightly,
/// No known track.
Unknown,
}
impl Into<ReleaseTrack> for updater::ReleaseTrack {
fn into(self) -> ReleaseTrack {
match self {
updater::ReleaseTrack::Stable => ReleaseTrack::Stable,
updater::ReleaseTrack::Beta => ReleaseTrack::Beta,
updater::ReleaseTrack::Nightly => ReleaseTrack::Nightly,
updater::ReleaseTrack::Unknown => ReleaseTrack::Unknown,
}
}
}
/// Semantic version.
#[derive(Debug, PartialEq, Serialize)]
pub struct Version {
/// Major part.
major: u64,
/// Minor part.
minor: u64,
/// Patch part.
patch: u64,
}
impl Into<Version> for semver::Version {
fn into(self) -> Version {
Version {
major: self.major,
minor: self.minor,
patch: self.patch,
}
}
}
/// Version information of a particular release.
#[derive(Debug, PartialEq, Serialize)]
pub struct VersionInfo {
/// The track on which it was released.
pub track: ReleaseTrack,
/// The version.
pub version: Version,
/// The (SHA1?) 160-bit hash of this build's code base.
pub hash: H160,
}
impl Into<VersionInfo> for updater::VersionInfo {
fn into(self) -> VersionInfo {
VersionInfo {
track: self.track.into(),
version: self.version.into(),
hash: self.hash.into(),
}
}
}
/// Information regarding a particular release of Parity
#[derive(Debug, PartialEq, Serialize)]
pub struct ReleaseInfo {
/// Information on the version.
pub version: VersionInfo,
/// Does this release contain critical security updates?
pub is_critical: bool,
/// The latest fork that this release can handle.
pub fork: u64,
/// Our platform's binary, if known.
pub binary: Option<H256>,
}
impl Into<ReleaseInfo> for updater::ReleaseInfo {
fn into(self) -> ReleaseInfo {
ReleaseInfo {
version: self.version.into(),
is_critical: self.is_critical,
fork: self.fork,
binary: self.binary.map(Into::into),
}
}
}
/// Information on our operations environment.
#[derive(Debug, PartialEq, Serialize)]
pub struct OperationsInfo {
/// Our blockchain's latest fork.
pub fork: u64,
/// Last fork our client supports, if known.
pub this_fork: Option<u64>,
/// Information on our track's latest release.
pub track: ReleaseInfo,
/// Information on our minor version's latest release.
pub minor: Option<ReleaseInfo>,
}
impl Into<OperationsInfo> for updater::OperationsInfo {
fn into(self) -> OperationsInfo {
OperationsInfo {
fork: self.fork,
this_fork: self.this_fork,
track: self.track.into(),
minor: self.minor.map(Into::into),
}
}
}

View File

@ -56,4 +56,4 @@ pub use self::trace_filter::TraceFilter;
pub use self::uint::{U128, U256}; pub use self::uint::{U128, U256};
pub use self::work::Work; pub use self::work::Work;
pub use self::histogram::Histogram; pub use self::histogram::Histogram;
pub use self::consensus_status::ConsensusCapability; pub use self::consensus_status::*;

View File

@ -137,8 +137,13 @@ impl Updater {
fn collect_latest(&self) -> Result<OperationsInfo, String> { fn collect_latest(&self) -> Result<OperationsInfo, String> {
if let Some(ref operations) = *self.operations.lock() { if let Some(ref operations) = *self.operations.lock() {
let hh: H256 = self.this.hash.into();
info!("Looking up this_fork for our release: {}/{:?}", CLIENT_ID, hh);
let this_fork = operations.release(CLIENT_ID, &self.this.hash.into()).ok() let this_fork = operations.release(CLIENT_ID, &self.this.hash.into()).ok()
.and_then(|(fork, track, _, _)| if track > 0 {Some(fork as u64)} else {None}); .and_then(|(fork, track, _, _)| {
info!("Operations returned fork={}, track={}", fork as u64, track);
if track > 0 {Some(fork as u64)} else {None}
});
if self.this.track == ReleaseTrack::Unknown { if self.this.track == ReleaseTrack::Unknown {
return Err(format!("Current executable ({}) is unreleased.", H160::from(self.this.hash))); return Err(format!("Current executable ({}) is unreleased.", H160::from(self.this.hash)));
@ -207,7 +212,7 @@ impl Updater {
} }
fn poll(&self) { fn poll(&self) {
info!(target: "updater", "Current release is {}", self.this); info!(target: "updater", "Current release is {} ({:?})", self.this, self.this.hash);
if self.operations.lock().is_none() { if self.operations.lock().is_none() {
if let Some(ops_addr) = self.client.upgrade().and_then(|c| c.registry_address("operations".into())) { if let Some(ops_addr) = self.client.upgrade().and_then(|c| c.registry_address("operations".into())) {