from/to for BlockLocation
This commit is contained in:
parent
ef34b3d9aa
commit
bd2149406d
@ -17,6 +17,8 @@
|
||||
use util::numbers::{U256,H256};
|
||||
use header::BlockNumber;
|
||||
|
||||
use util::bytes::{FromRawBytesVariable, FromBytesError, ToBytesWithMap};
|
||||
|
||||
/// Brief info about inserted block.
|
||||
#[derive(Clone)]
|
||||
pub struct BlockInfo {
|
||||
@ -40,12 +42,41 @@ pub enum BlockLocation {
|
||||
/// It's part of the fork which should become canon chain,
|
||||
/// because it's total difficulty is higher than current
|
||||
/// canon chain difficulty.
|
||||
BranchBecomingCanonChain {
|
||||
BranchBecomingCanonChain(BranchBecomingCanonChainData),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BranchBecomingCanonChainData {
|
||||
/// Hash of the newest common ancestor with old canon chain.
|
||||
ancestor: H256,
|
||||
pub ancestor: H256,
|
||||
/// Hashes of the blocks between ancestor and this block.
|
||||
enacted: Vec<H256>,
|
||||
pub enacted: Vec<H256>,
|
||||
/// Hashes of the blocks which were invalidated.
|
||||
retracted: Vec<H256>,
|
||||
pub retracted: Vec<H256>,
|
||||
}
|
||||
|
||||
impl FromRawBytesVariable for BranchBecomingCanonChainData {
|
||||
fn from_bytes_variable(bytes: &[u8]) -> Result<BranchBecomingCanonChainData, FromBytesError> {
|
||||
type Tuple = (Vec<H256>, Vec<H256>, H256);
|
||||
let (enacted, retracted, ancestor) = try!(Tuple::from_bytes_variable(bytes));
|
||||
Ok(BranchBecomingCanonChainData { ancestor: ancestor, enacted: enacted, retracted: retracted })
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRawBytesVariable for BlockLocation {
|
||||
fn from_bytes_variable(bytes: &[u8]) -> Result<BlockLocation, FromBytesError> {
|
||||
match bytes[0] {
|
||||
0 => Ok(BlockLocation::CanonChain),
|
||||
1 => Ok(BlockLocation::Branch),
|
||||
2 => Ok(BlockLocation::BranchBecomingCanonChain(
|
||||
try!(BranchBecomingCanonChainData::from_bytes_variable(&bytes[1..bytes.len()])))),
|
||||
_ => Err(FromBytesError::UnknownMarker)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToBytesWithMap for BranchBecomingCanonChainData {
|
||||
fn to_bytes_map(&self) -> Vec<u8> {
|
||||
(&self.enacted, &self.retracted, &self.ancestor).to_bytes_map()
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ use transaction::*;
|
||||
use views::*;
|
||||
use receipt::Receipt;
|
||||
use chainfilter::{ChainFilter, BloomIndex, FilterDataSource};
|
||||
use blockchain::block_info::{BlockInfo, BlockLocation};
|
||||
use blockchain::block_info::{BlockInfo, BlockLocation, BranchBecomingCanonChainData};
|
||||
use blockchain::best_block::BestBlock;
|
||||
use blockchain::bloom_indexer::BloomIndexer;
|
||||
use blockchain::tree_route::TreeRoute;
|
||||
@ -582,11 +582,11 @@ impl BlockChain {
|
||||
_ => {
|
||||
let retracted = route.blocks.iter().take(route.index).cloned().collect::<Vec<H256>>();
|
||||
|
||||
BlockLocation::BranchBecomingCanonChain {
|
||||
BlockLocation::BranchBecomingCanonChain(BranchBecomingCanonChainData {
|
||||
ancestor: route.ancestor,
|
||||
enacted: route.blocks.into_iter().skip(route.index).collect(),
|
||||
retracted: retracted.into_iter().rev().collect(),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -607,11 +607,11 @@ impl BlockChain {
|
||||
BlockLocation::CanonChain => {
|
||||
block_hashes.insert(number, info.hash.clone());
|
||||
},
|
||||
BlockLocation::BranchBecomingCanonChain { ref ancestor, ref enacted, .. } => {
|
||||
let ancestor_number = self.block_number(ancestor).unwrap();
|
||||
BlockLocation::BranchBecomingCanonChain(ref data) => {
|
||||
let ancestor_number = self.block_number(&data.ancestor).unwrap();
|
||||
let start_number = ancestor_number + 1;
|
||||
|
||||
for (index, hash) in enacted.iter().cloned().enumerate() {
|
||||
for (index, hash) in data.enacted.iter().cloned().enumerate() {
|
||||
block_hashes.insert(start_number + index as BlockNumber, hash);
|
||||
}
|
||||
|
||||
@ -696,11 +696,11 @@ impl BlockChain {
|
||||
ChainFilter::new(self, self.bloom_indexer.index_size(), self.bloom_indexer.levels())
|
||||
.add_bloom(&header.log_bloom(), header.number() as usize)
|
||||
},
|
||||
BlockLocation::BranchBecomingCanonChain { ref ancestor, ref enacted, .. } => {
|
||||
let ancestor_number = self.block_number(ancestor).unwrap();
|
||||
BlockLocation::BranchBecomingCanonChain(ref data) => {
|
||||
let ancestor_number = self.block_number(&data.ancestor).unwrap();
|
||||
let start_number = ancestor_number + 1;
|
||||
|
||||
let mut blooms: Vec<H2048> = enacted.iter()
|
||||
let mut blooms: Vec<H2048> = data.enacted.iter()
|
||||
.map(|hash| self.block(hash).unwrap())
|
||||
.map(|bytes| BlockView::new(&bytes).header_view().log_bloom())
|
||||
.collect();
|
||||
|
@ -45,11 +45,11 @@ impl From<BlockInfo> for ImportRoute {
|
||||
enacted: vec![info.hash],
|
||||
},
|
||||
BlockLocation::Branch => ImportRoute::none(),
|
||||
BlockLocation::BranchBecomingCanonChain { mut enacted, retracted, .. } => {
|
||||
enacted.push(info.hash);
|
||||
BlockLocation::BranchBecomingCanonChain(mut data) => {
|
||||
data.enacted.push(info.hash);
|
||||
ImportRoute {
|
||||
retracted: retracted,
|
||||
enacted: enacted,
|
||||
retracted: data.retracted,
|
||||
enacted: data.enacted,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ impl From<BlockInfo> for ImportRoute {
|
||||
mod tests {
|
||||
use util::hash::H256;
|
||||
use util::numbers::U256;
|
||||
use blockchain::block_info::{BlockInfo, BlockLocation};
|
||||
use blockchain::block_info::{BlockInfo, BlockLocation, BranchBecomingCanonChainData};
|
||||
use blockchain::ImportRoute;
|
||||
|
||||
#[test]
|
||||
@ -104,11 +104,11 @@ mod tests {
|
||||
hash: H256::from(U256::from(2)),
|
||||
number: 0,
|
||||
total_difficulty: U256::from(0),
|
||||
location: BlockLocation::BranchBecomingCanonChain {
|
||||
location: BlockLocation::BranchBecomingCanonChain(BranchBecomingCanonChainData {
|
||||
ancestor: H256::from(U256::from(0)),
|
||||
enacted: vec![H256::from(U256::from(1))],
|
||||
retracted: vec![H256::from(U256::from(3)), H256::from(U256::from(4))],
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
assert_eq!(ImportRoute::from(info), ImportRoute {
|
||||
|
@ -241,6 +241,8 @@ pub enum FromBytesError {
|
||||
NotLongEnough,
|
||||
/// Too many bytes for the requested type
|
||||
TooLong,
|
||||
/// Invalid marker for (enums)
|
||||
UnknownMarker,
|
||||
}
|
||||
|
||||
/// Value that can be serialized from bytes array
|
||||
@ -330,27 +332,120 @@ impl<V1, T2> FromRawBytes for (V1, T2) where V1: FromRawBytesVariable, T2: FromR
|
||||
}
|
||||
}
|
||||
|
||||
impl<V1, T2> BytesConvertable for (Vec<V1>, T2) where V1: BytesConvertable, T2: BytesConvertable {
|
||||
fn bytes(&self) -> &[u8] {
|
||||
impl<V1, V2, T3> FromRawBytes for (V1, V2, T3)
|
||||
where V1: FromRawBytesVariable,
|
||||
V2: FromRawBytesVariable,
|
||||
T3: FromRawBytes
|
||||
{
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self, FromBytesError> {
|
||||
let header = 16usize;
|
||||
let mut map: (u64, u64, ) = unsafe { mem::uninitialized() };
|
||||
|
||||
if bytes.len() < header { return Err(FromBytesError::NotLongEnough); }
|
||||
map.copy_raw(&bytes[0..header]);
|
||||
|
||||
let map_1 = (header, header + map.0 as usize);
|
||||
let map_2 = (map_1.1 as usize, map_1.1 as usize + map.1 as usize);
|
||||
Ok((
|
||||
try!(V1::from_bytes_variable(&bytes[map_1.0..map_1.1])),
|
||||
try!(V2::from_bytes_variable(&bytes[map_2.0..map_2.1])),
|
||||
try!(T3::from_bytes(&bytes[map_2.1..bytes.len()])),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V1, T2> ToBytesWithMap for (&'a Vec<V1>, &'a T2) where V1: ToBytesWithMap, T2: ToBytesWithMap {
|
||||
fn to_bytes_map(&self) -> Vec<u8> {
|
||||
let header = 8usize;
|
||||
let mut result = Vec::new(header + self.0.len() * mem::size_of::<V1>() + mem::size_of::<T2>());
|
||||
let v1_size = mem::size_of::<V1>();
|
||||
let mut result = Vec::with_capacity(header + self.0.len() * v1_size + mem::size_of::<T2>());
|
||||
result.extend(((self.0.len() * v1_size) as u64).to_bytes_map());
|
||||
|
||||
*result[0..header] = (self.0.len() as u64).as_slice();
|
||||
for i in 0..self.0.len() {
|
||||
*result[header + i*mem::size_of::<V1>()..header + (i+1)*mem::size_of::<V1>()] =
|
||||
self.0[i].as_slice();
|
||||
result.extend(self.0[i].to_bytes_map());
|
||||
}
|
||||
*result[header + self.0.len()..result.len()] = self.1.as_slice();
|
||||
result.extend(self.1.to_bytes_map());
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<'a, V1, V2, T3> ToBytesWithMap for (&'a Vec<V1>, &'a Vec<V2>, &'a T3)
|
||||
where V1: ToBytesWithMap,
|
||||
V2: ToBytesWithMap,
|
||||
T3: ToBytesWithMap
|
||||
{
|
||||
fn to_bytes_map(&self) -> Vec<u8> {
|
||||
let header = 16usize;
|
||||
let v1_size = mem::size_of::<V1>();
|
||||
let v2_size = mem::size_of::<V2>();
|
||||
let mut result = Vec::with_capacity(
|
||||
header +
|
||||
self.0.len() * v1_size +
|
||||
self.1.len() * v2_size +
|
||||
mem::size_of::<T3>()
|
||||
);
|
||||
result.extend(((self.0.len() * v1_size) as u64).to_bytes_map());
|
||||
result.extend(((self.1.len() * v1_size) as u64).to_bytes_map());
|
||||
for i in 0..self.0.len() {
|
||||
result.extend(self.0[i].to_bytes_map());
|
||||
}
|
||||
for i in 0..self.1.len() {
|
||||
result.extend(self.1[i].to_bytes_map());
|
||||
}
|
||||
result.extend(self.2.to_bytes_map());
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRawBytesVariable for Vec<u8> {
|
||||
fn from_bytes_variable(bytes: &[u8]) -> Result<Vec<u8>, FromBytesError> {
|
||||
Ok(bytes.clone().to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToBytesWithMap {
|
||||
fn to_bytes_map(&self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
impl<T> ToBytesWithMap for T where T: FixedHash {
|
||||
fn to_bytes_map(&self) -> Vec<u8> {
|
||||
self.as_slice().to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToBytesWithMap for u16 {
|
||||
fn to_bytes_map(&self) -> Vec<u8> {
|
||||
let sz = mem::size_of::<u16>();
|
||||
let mut res = Vec::<u8>::with_capacity(sz);
|
||||
|
||||
let ip: *const u16 = self;
|
||||
let ptr: *const u8 = ip as *const _;
|
||||
unsafe {
|
||||
res.set_len(sz);
|
||||
::std::ptr::copy(ptr, res.as_mut_ptr(), sz);
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl ToBytesWithMap for u64 {
|
||||
fn to_bytes_map(&self) -> Vec<u8> {
|
||||
let sz = mem::size_of::<u64>();
|
||||
let mut res = Vec::<u8>::with_capacity(sz);
|
||||
|
||||
let ip: *const u64 = self;
|
||||
let ptr: *const u8 = ip as *const _;
|
||||
unsafe {
|
||||
res.set_len(sz);
|
||||
::std::ptr::copy(ptr, res.as_mut_ptr(), sz);
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fax_raw() {
|
||||
let mut x = [255u8; 4];
|
||||
@ -422,6 +517,7 @@ fn raw_bytes_from_tuple() {
|
||||
let tup_from = Tup::from_bytes(&bytes).unwrap();
|
||||
assert_eq!(tup, tup_from);
|
||||
|
||||
let bytes_to = Tup::as_slice();
|
||||
let tup_to = (&tup_from.0, &tup_from.1);
|
||||
let bytes_to = tup_to.to_bytes_map();
|
||||
assert_eq!(bytes_to, bytes);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user