Block import and export (#272)

* Block export and import

* Export and import using std streams

* Made AuthorituId::from_slice private
This commit is contained in:
Arkadiy Paronyan authored and Gav Wood committed 2018-07-03 20:20:53 +02:00
1 parent 12268ae700
commit aa747e3fae
10 files changed
+267 -25

No files matched your search

+10 -1
View File
@@ -20,7 +20,7 @@ use std::sync::Arc;
use futures::sync::mpsc;
use parking_lot::{Mutex, RwLock};
use primitives::AuthorityId;
use runtime_primitives::{bft::Justification, generic::BlockId};
use runtime_primitives::{bft::Justification, generic::{BlockId, SignedBlock, Block as RuntimeBlock}};
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, One};
use runtime_primitives::BuildStorage;
use primitives::storage::{StorageKey, StorageData};
@@ -416,6 +416,15 @@ impl<B, E, Block> Client<B, E, Block> where
self.backend.blockchain().justification(*id)
}
/// Get full block by id.
pub fn block(&self, id: &BlockId<Block>) -> error::Result<Option<SignedBlock<Block::Header, Block::Extrinsic, Block::Hash>>> {
Ok(match (self.header(id)?, self.body(id)?, self.justification(id)?) {
(Some(header), Some(extrinsics), Some(justification)) =>
Some(SignedBlock { block: RuntimeBlock { header, extrinsics }, justification }),
_ => None,
})
}
/// Get best block header.
pub fn best_block_header(&self) -> error::Result<<Block as BlockT>::Header> {
let info = self.backend.blockchain().info().map_err(|e| error::Error::from_blockchain(Box::new(e)))?;
+1 -1
View File
@@ -53,7 +53,7 @@ pub use client::{
new_in_mem,
BlockStatus, BlockOrigin, BlockchainEventStream, BlockchainEvents,
Client, ClientInfo, ChainHead,
ImportResult,
ImportResult, JustifiedHeader,
};
pub use blockchain::Info as ChainInfo;
pub use call_executor::{CallResult, CallExecutor, LocalCallExecutor};
@@ -38,6 +38,7 @@ pub trait Input {
}
}
#[cfg(not(feature = "std"))]
impl<'a> Input for &'a [u8] {
fn read(&mut self, into: &mut [u8]) -> usize {
let len = ::core::cmp::min(into.len(), self.len());
@@ -47,6 +48,13 @@ impl<'a> Input for &'a [u8] {
}
}
#[cfg(feature = "std")]
impl<R: ::std::io::Read> Input for R {
fn read(&mut self, into: &mut [u8]) -> usize {
(self as &mut ::std::io::Read).read(into).unwrap_or(0)
}
}
/// Trait that allows zero-copy read/write of value-references to/from slices in LE format.
pub trait Slicable: Sized {
/// Attempt to deserialise the value from input.
@@ -25,8 +25,8 @@ use H256;
pub struct AuthorityId(pub [u8; 32]);
impl AuthorityId {
/// Create an id from byte slice.
pub fn from_slice(data: &[u8]) -> Self {
/// Create an id from a 32-byte slice. Panics with other lengths.
fn from_slice(data: &[u8]) -> Self {
let mut r = [0u8; 32];
r.copy_from_slice(data);
AuthorityId(r)
@@ -28,6 +28,7 @@ use runtime_support::AuxDispatchable;
use traits::{self, Member, SimpleArithmetic, SimpleBitOps, MaybeDisplay, Block as BlockT,
Header as HeaderT, Hashing as HashingT};
use rstd::ops;
use bft::Justification;
/// Definition of something that the external world might want to say.
#[derive(PartialEq, Eq, Clone)]
@@ -476,6 +477,34 @@ where
}
}
/// Abstraction over a substrate block and justification.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct SignedBlock<Header, Extrinsic, Hash> {
/// Full block.
pub block: Block<Header, Extrinsic>,
/// Block header justification.
pub justification: Justification<Hash>,
}
impl<Header: Slicable, Extrinsic: Slicable, Hash: Slicable> Slicable for SignedBlock<Header, Extrinsic, Hash> {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(SignedBlock {
block: Slicable::decode(input)?,
justification: Slicable::decode(input)?,
})
}
fn encode(&self) -> Vec<u8> {
let mut v: Vec<u8> = Vec::new();
v.extend(self.block.encode());
v.extend(self.justification.encode());
v
}
}
#[cfg(test)]
mod tests {
use codec::Slicable;