Phase 1 of repo reorg (#719)

* Remove unneeded script

* Rename Substrate Demo -> Substrate

* Rename demo -> node

* Build wasm from last rename.

* Merge ed25519 into substrate-primitives

* Minor tweak

* Rename substrate -> core

* Move substrate-runtime-support to core/runtime/support

* Rename/move substrate-runtime-version

* Move codec up a level

* Rename substrate-codec -> parity-codec

* Move environmental up a level

* Move pwasm-* up to top, ready for removal

* Remove requirement of s-r-support from s-r-primitives

* Move core/runtime/primitives into core/runtime-primitives

* Remove s-r-support dep from s-r-version

* Remove dep of s-r-support from bft

* Remove dep of s-r-support from node/consensus

* Sever all other core deps from s-r-support

* Forgot the no_std directive

* Rename non-SRML modules to sr-* to avoid match clashes

* Move runtime/* to srml/*

* Rename substrate-runtime-* -> srml-*

* Move srml to top-level
This commit is contained in:
Gav Wood
2018-09-12 11:13:31 +02:00
committed by Arkadiy Paronyan
parent 8fe5aa4c81
commit 1e01162505
374 changed files with 2845 additions and 2902 deletions
+68
View File
@@ -0,0 +1,68 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
//! Authoring RPC module errors.
use client;
use extrinsic_pool;
use rpc;
use errors;
error_chain! {
links {
Pool(extrinsic_pool::Error, extrinsic_pool::ErrorKind) #[doc = "Pool error"];
Client(client::error::Error, client::error::ErrorKind) #[doc = "Client error"];
}
errors {
/// Not implemented yet
Unimplemented {
description("not yet implemented"),
display("Method Not Implemented"),
}
/// Incorrect extrinsic format.
BadFormat {
description("bad format"),
display("Invalid extrinsic format"),
}
/// Verification error
Verification(e: Box<::std::error::Error + Send>) {
description("extrinsic verification error"),
display("Extrinsic verification error: {}", e.description()),
}
}
}
const ERROR: i64 = 1000;
impl From<Error> for rpc::Error {
fn from(e: Error) -> Self {
match e {
Error(ErrorKind::Unimplemented, _) => errors::unimplemented(),
Error(ErrorKind::BadFormat, _) => rpc::Error {
code: rpc::ErrorCode::ServerError(ERROR + 1),
message: "Extrinsic has invalid format.".into(),
data: None,
},
Error(ErrorKind::Verification(e), _) => rpc::Error {
code: rpc::ErrorCode::ServerError(ERROR + 2),
message: e.description().into(),
data: Some(format!("{:?}", e).into()),
},
e => errors::internal(e),
}
}
}
+162
View File
@@ -0,0 +1,162 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
//! Substrate block-author/full-node API.
use std::sync::Arc;
use client::{self, Client};
use codec::Decode;
use extrinsic_pool::{
Pool,
IntoPoolError,
ChainApi as PoolChainApi,
watcher::Status,
VerifiedTransaction,
AllExtrinsics,
ExHash,
ExtrinsicFor,
};
use jsonrpc_macros::pubsub;
use jsonrpc_pubsub::SubscriptionId;
use primitives::{Bytes, Blake2Hasher, RlpCodec};
use rpc::futures::{Sink, Stream, Future};
use runtime_primitives::{generic, traits};
use subscriptions::Subscriptions;
use tokio::runtime::TaskExecutor;
pub mod error;
#[cfg(test)]
mod tests;
use self::error::Result;
build_rpc_trait! {
/// Substrate authoring RPC API
pub trait AuthorApi<Hash, Extrinsic, PendingExtrinsics> {
type Metadata;
/// Submit extrinsic for inclusion in block.
#[rpc(name = "author_submitRichExtrinsic")]
fn submit_rich_extrinsic(&self, Extrinsic) -> Result<Hash>;
/// Submit hex-encoded extrinsic for inclusion in block.
#[rpc(name = "author_submitExtrinsic")]
fn submit_extrinsic(&self, Bytes) -> Result<Hash>;
/// Returns all pending extrinsics, potentially grouped by sender.
#[rpc(name = "author_pendingExtrinsics")]
fn pending_extrinsics(&self) -> Result<PendingExtrinsics>;
#[pubsub(name = "author_extrinsicUpdate")] {
/// Submit an extrinsic to watch.
#[rpc(name = "author_submitAndWatchExtrinsic")]
fn watch_extrinsic(&self, Self::Metadata, pubsub::Subscriber<Status<Hash>>, Bytes);
/// Unsubscribe from extrinsic watching.
#[rpc(name = "author_unwatchExtrinsic")]
fn unwatch_extrinsic(&self, SubscriptionId) -> Result<bool>;
}
}
}
/// Authoring API
pub struct Author<B, E, P> where
P: PoolChainApi + Sync + Send + 'static,
{
/// Substrate client
client: Arc<Client<B, E, <P as PoolChainApi>::Block>>,
/// Extrinsic pool
pool: Arc<Pool<P>>,
/// Subscriptions manager
subscriptions: Subscriptions,
}
impl<B, E, P> Author<B, E, P> where
P: PoolChainApi + Sync + Send + 'static,
{
/// Create new instance of Authoring API.
pub fn new(client: Arc<Client<B, E, <P as PoolChainApi>::Block>>, pool: Arc<Pool<P>>, executor: TaskExecutor) -> Self {
Author {
client,
pool,
subscriptions: Subscriptions::new(executor),
}
}
}
impl<B, E, P> AuthorApi<ExHash<P>, ExtrinsicFor<P>, AllExtrinsics<P>> for Author<B, E, P> where
B: client::backend::Backend<<P as PoolChainApi>::Block, Blake2Hasher, RlpCodec> + Send + Sync + 'static,
E: client::CallExecutor<<P as PoolChainApi>::Block, Blake2Hasher, RlpCodec> + Send + Sync + 'static,
P: PoolChainApi + Sync + Send + 'static,
P::Error: 'static,
{
type Metadata = ::metadata::Metadata;
fn submit_extrinsic(&self, xt: Bytes) -> Result<ExHash<P>> {
let dxt = Decode::decode(&mut &xt[..]).ok_or(error::Error::from(error::ErrorKind::BadFormat))?;
self.submit_rich_extrinsic(dxt)
}
fn submit_rich_extrinsic(&self, xt: <<P as PoolChainApi>::Block as traits::Block>::Extrinsic) -> Result<ExHash<P>> {
let best_block_hash = self.client.info()?.chain.best_hash;
self.pool
.submit_one(&generic::BlockId::hash(best_block_hash), xt)
.map_err(|e| e.into_pool_error()
.map(Into::into)
.unwrap_or_else(|e| error::ErrorKind::Verification(Box::new(e)).into())
)
.map(|ex| ex.hash().clone())
}
fn pending_extrinsics(&self) -> Result<AllExtrinsics<P>> {
Ok(self.pool.all())
}
fn watch_extrinsic(&self, _metadata: Self::Metadata, subscriber: pubsub::Subscriber<Status<ExHash<P>>>, xt: Bytes) {
let submit = || -> Result<_> {
let best_block_hash = self.client.info()?.chain.best_hash;
let dxt = <<P as PoolChainApi>::Block as traits::Block>::Extrinsic::decode(&mut &xt[..]).ok_or(error::Error::from(error::ErrorKind::BadFormat))?;
self.pool
.submit_and_watch(&generic::BlockId::hash(best_block_hash), dxt)
.map_err(|e| e.into_pool_error()
.map(Into::into)
.unwrap_or_else(|e| error::ErrorKind::Verification(Box::new(e)).into())
)
};
let watcher = match submit() {
Ok(watcher) => watcher,
Err(err) => {
// reject the subscriber (ignore errors - we don't care if subscriber is no longer there).
let _ = subscriber.reject(err.into());
return;
},
};
self.subscriptions.add(subscriber, move |sink| {
sink
.sink_map_err(|e| warn!("Error sending notifications: {:?}", e))
.send_all(watcher.into_stream().map(Ok))
.map(|_| ())
})
}
fn unwatch_extrinsic(&self, id: SubscriptionId) -> Result<bool> {
Ok(self.subscriptions.cancel(id))
}
}
+178
View File
@@ -0,0 +1,178 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
use super::*;
use std::{sync::Arc, result::Result};
use codec::Encode;
use extrinsic_pool::{VerifiedTransaction, scoring, Transaction, ChainApi, Error as PoolError,
Readiness, ExtrinsicFor, VerifiedFor};
use test_client::runtime::{Block, Extrinsic, Transfer};
use test_client;
use tokio::runtime;
use runtime_primitives::generic::BlockId;
#[derive(Clone, Debug)]
pub struct Verified
{
sender: u64,
hash: u64,
}
impl VerifiedTransaction for Verified {
type Hash = u64;
type Sender = u64;
fn hash(&self) -> &Self::Hash { &self.hash }
fn sender(&self) -> &Self::Sender { &self.sender }
fn mem_usage(&self) -> usize { 256 }
}
struct TestApi;
impl ChainApi for TestApi {
type Block = Block;
type Hash = u64;
type Sender = u64;
type Error = PoolError;
type VEx = Verified;
type Score = u64;
type Event = ();
type Ready = ();
fn verify_transaction(&self, _at: &BlockId<Block>, uxt: &ExtrinsicFor<Self>) -> Result<Self::VEx, Self::Error> {
Ok(Verified {
sender: uxt.transfer.from[31] as u64,
hash: uxt.transfer.nonce,
})
}
fn is_ready(&self, _at: &BlockId<Block>, _c: &mut Self::Ready, _xt: &VerifiedFor<Self>) -> Readiness {
Readiness::Ready
}
fn ready(&self) -> Self::Ready { }
fn compare(old: &VerifiedFor<Self>, other: &VerifiedFor<Self>) -> ::std::cmp::Ordering {
old.verified.hash().cmp(&other.verified.hash())
}
fn choose(_old: &VerifiedFor<Self>, _new: &VerifiedFor<Self>) -> scoring::Choice {
scoring::Choice::ReplaceOld
}
fn update_scores(xts: &[Transaction<VerifiedFor<Self>>], scores: &mut [Self::Score], _change: scoring::Change<()>) {
for i in 0..xts.len() {
scores[i] = xts[i].verified.sender
}
}
fn should_replace(_old: &VerifiedFor<Self>, _new: &VerifiedFor<Self>) -> scoring::Choice {
scoring::Choice::ReplaceOld
}
}
type DummyTxPool = Pool<TestApi>;
fn uxt(sender: u64, hash: u64) -> Extrinsic {
Extrinsic {
signature: Default::default(),
transfer: Transfer {
amount: Default::default(),
nonce: hash,
from: From::from(sender),
to: Default::default(),
}
}
}
#[test]
fn submit_transaction_should_not_cause_error() {
let runtime = runtime::Runtime::new().unwrap();
let p = Author {
client: Arc::new(test_client::new()),
pool: Arc::new(DummyTxPool::new(Default::default(), TestApi)),
subscriptions: Subscriptions::new(runtime.executor()),
};
assert_matches!(
AuthorApi::submit_extrinsic(&p, uxt(5, 1).encode().into()),
Ok(1)
);
assert!(
AuthorApi::submit_extrinsic(&p, uxt(5, 1).encode().into()).is_err()
);
}
#[test]
fn submit_rich_transaction_should_not_cause_error() {
let runtime = runtime::Runtime::new().unwrap();
let p = Author {
client: Arc::new(test_client::new()),
pool: Arc::new(DummyTxPool::new(Default::default(), TestApi)),
subscriptions: Subscriptions::new(runtime.executor()),
};
assert_matches!(
AuthorApi::submit_rich_extrinsic(&p, uxt(5, 0)),
Ok(0)
);
assert!(
AuthorApi::submit_rich_extrinsic(&p, uxt(5, 0)).is_err()
);
}
#[test]
fn should_watch_extrinsic() {
//given
let mut runtime = runtime::Runtime::new().unwrap();
let pool = Arc::new(DummyTxPool::new(Default::default(), TestApi));
let p = Author {
client: Arc::new(test_client::new()),
pool: pool.clone(),
subscriptions: Subscriptions::new(runtime.executor()),
};
let (subscriber, id_rx, data) = ::jsonrpc_macros::pubsub::Subscriber::new_test("test");
// when
p.watch_extrinsic(Default::default(), subscriber, uxt(5, 5).encode().into());
// then
assert_eq!(runtime.block_on(id_rx), Ok(Ok(0.into())));
// check notifications
AuthorApi::submit_rich_extrinsic(&p, uxt(5, 1)).unwrap();
assert_eq!(
runtime.block_on(data.into_future()).unwrap().0,
Some(r#"{"jsonrpc":"2.0","method":"test","params":{"result":{"usurped":1},"subscription":0}}"#.into())
);
}
#[test]
fn should_return_pending_extrinsics() {
let runtime = runtime::Runtime::new().unwrap();
let pool = Arc::new(DummyTxPool::new(Default::default(), TestApi));
let p = Author {
client: Arc::new(test_client::new()),
pool: pool.clone(),
subscriptions: Subscriptions::new(runtime.executor()),
};
let ex = uxt(5, 1);
AuthorApi::submit_rich_extrinsic(&p, ex.clone()).unwrap();
assert_matches!(
p.pending_extrinsics(),
Ok(ref expected) if expected.get(&5) == Some(&vec![ex])
);
}