Substrate relay stub (#376)

* substrate-relay: initial commit

* MillauHeaderApi and RialtoHeaderApi

* post-merge fixes + TODOs + compilation
This commit is contained in:
Svyatoslav Nikolsky
2020-09-30 14:03:57 +03:00
committed by Bastian Köcher
parent f9db999a1a
commit dbb72faa86
22 changed files with 652 additions and 71 deletions
+29 -4
View File
@@ -19,9 +19,13 @@ use crate::client::Client;
use frame_support::Parameter;
use jsonrpsee::common::{DeserializeOwned, Serialize};
use sp_core::Pair;
use sp_runtime::traits::{
AtLeast32Bit, AtLeast32BitUnsigned, Bounded, CheckEqual, Dispatchable, Header as HeaderT, MaybeDisplay,
MaybeMallocSizeOf, MaybeSerialize, MaybeSerializeDeserialize, Member, SimpleBitOps,
use sp_runtime::{
generic::SignedBlock,
traits::{
AtLeast32Bit, AtLeast32BitUnsigned, Bounded, CheckEqual, Dispatchable, Header as HeaderT, MaybeDisplay,
MaybeMallocSizeOf, MaybeSerialize, MaybeSerializeDeserialize, Member, SimpleBitOps,
},
Justification,
};
use sp_std::fmt::Debug;
@@ -63,11 +67,17 @@ pub trait Chain {
/// with a sender account.
type Index: Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + AtLeast32Bit + Copy;
/// Block type.
type SignedBlock: Member + Serialize + DeserializeOwned;
type SignedBlock: Member + Serialize + DeserializeOwned + BlockWithJustification;
/// The aggregated `Call` type.
type Call: Dispatchable + Debug;
}
/// Block with justification.
pub trait BlockWithJustification {
/// Return block justification, if known.
fn justification(&self) -> Option<&Justification>;
}
/// Substrate-based chain transactions signing scheme.
pub trait TransactionSignScheme {
/// Chain that this scheme is to be used.
@@ -85,3 +95,18 @@ pub trait TransactionSignScheme {
call: <Self::Chain as Chain>::Call,
) -> Self::SignedTransaction;
}
/// Header type used by the chain.
pub type HeaderOf<C> = <C as Chain>::Header;
/// Hash type used by the chain.
pub type HashOf<C> = <C as Chain>::Hash;
/// Block number used by the chain.
pub type BlockNumberOf<C> = <C as Chain>::BlockNumber;
impl<Block> BlockWithJustification for SignedBlock<Block> {
fn justification(&self) -> Option<&Justification> {
self.justification.as_ref()
}
}
@@ -45,6 +45,12 @@ impl MaybeConnectionError for Error {
}
}
impl From<Error> for String {
fn from(error: Error) -> String {
error.to_string()
}
}
impl ToString for Error {
fn to_string(&self) -> String {
match self {
@@ -0,0 +1,99 @@
// Copyright 2019-2020 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.
// Parity Bridges Common 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.
// Parity Bridges Common 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 Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
//! Default generic implementation of headers source for basic Substrate client.
use crate::chain::{BlockWithJustification, Chain};
use crate::client::Client;
use crate::error::Error;
use async_trait::async_trait;
use headers_relay::{
sync_loop::SourceClient,
sync_types::{HeaderIdOf, HeadersSyncPipeline, QueuedHeader, SourceHeader},
};
use jsonrpsee::common::DeserializeOwned;
use num_traits::Saturating;
use sp_runtime::{traits::Header as HeaderT, Justification};
use std::marker::PhantomData;
/// Substrate node as headers source.
pub struct HeadersSource<C: Chain, P> {
client: Client<C>,
_phantom: PhantomData<P>,
}
impl<C: Chain, P> HeadersSource<C, P> {
/// Create new headers source using given client.
pub fn new(client: Client<C>) -> Self {
HeadersSource {
client,
_phantom: Default::default(),
}
}
}
#[async_trait]
impl<C, P> SourceClient<P> for HeadersSource<C, P>
where
C: Chain,
C::BlockNumber: Into<u64> + Saturating,
C::Header: DeserializeOwned + Into<P::Header>,
C::Index: DeserializeOwned,
P: HeadersSyncPipeline<Extra = (), Completion = Justification, Hash = C::Hash, Number = C::BlockNumber>,
P::Header: SourceHeader<C::Hash, C::BlockNumber>,
{
type Error = Error;
async fn best_block_number(&self) -> Result<P::Number, Self::Error> {
Ok(*self.client.best_header().await?.number())
}
async fn header_by_hash(&self, hash: P::Hash) -> Result<P::Header, Self::Error> {
self.client
.header_by_hash(hash)
.await
.map(Into::into)
.map_err(Into::into)
}
async fn header_by_number(&self, number: P::Number) -> Result<P::Header, Self::Error> {
self.client
.header_by_number(number)
.await
.map(Into::into)
.map_err(Into::into)
}
async fn header_completion(
&self,
id: HeaderIdOf<P>,
) -> Result<(HeaderIdOf<P>, Option<P::Completion>), Self::Error> {
let hash = id.1;
let signed_block = self.client.get_block(Some(hash)).await?;
let grandpa_justification = signed_block.justification().cloned();
Ok((id, grandpa_justification))
}
async fn header_extra(
&self,
id: HeaderIdOf<P>,
_header: QueuedHeader<P>,
) -> Result<(HeaderIdOf<P>, ()), Self::Error> {
Ok((id, ()))
}
}
+3 -1
View File
@@ -23,7 +23,9 @@ mod client;
mod error;
mod rpc;
pub use crate::chain::{Chain, TransactionSignScheme};
pub mod headers_source;
pub use crate::chain::{BlockNumberOf, BlockWithJustification, Chain, HashOf, HeaderOf, TransactionSignScheme};
pub use crate::client::{Client, OpaqueGrandpaAuthoritiesSet};
pub use crate::error::{Error, Result};