Propagate uncles (#1134)
This commit is contained in:
parent
27380cdadb
commit
fba5082b00
@ -518,6 +518,11 @@ impl BlockChain {
|
|||||||
|
|
||||||
/// Given a block's `parent`, find every block header which represents a valid possible uncle.
|
/// Given a block's `parent`, find every block header which represents a valid possible uncle.
|
||||||
pub fn find_uncle_headers(&self, parent: &H256, uncle_generations: usize) -> Option<Vec<Header>> {
|
pub fn find_uncle_headers(&self, parent: &H256, uncle_generations: usize) -> Option<Vec<Header>> {
|
||||||
|
self.find_uncle_hashes(parent, uncle_generations).map(|v| v.into_iter().filter_map(|h| self.block_header(&h)).collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a block's `parent`, find every block hash which represents a valid possible uncle.
|
||||||
|
pub fn find_uncle_hashes(&self, parent: &H256, uncle_generations: usize) -> Option<Vec<H256>> {
|
||||||
if !self.is_known(parent) { return None; }
|
if !self.is_known(parent) { return None; }
|
||||||
|
|
||||||
let mut excluded = HashSet::new();
|
let mut excluded = HashSet::new();
|
||||||
@ -529,7 +534,7 @@ impl BlockChain {
|
|||||||
let mut ret = Vec::new();
|
let mut ret = Vec::new();
|
||||||
for a in self.ancestry_iter(parent.clone()).unwrap().skip(1).take(uncle_generations) {
|
for a in self.ancestry_iter(parent.clone()).unwrap().skip(1).take(uncle_generations) {
|
||||||
ret.extend(self.block_details(&a).unwrap().children.iter()
|
ret.extend(self.block_details(&a).unwrap().children.iter()
|
||||||
.filter_map(|h| if excluded.contains(h) { None } else { self.block_header(h) })
|
.filter(|h| !excluded.contains(h))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Some(ret)
|
Some(ret)
|
||||||
|
@ -622,6 +622,10 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_uncles(&self, hash: &H256) -> Option<Vec<H256>> {
|
||||||
|
self.chain.find_uncle_hashes(hash, self.engine.maximum_uncle_age())
|
||||||
|
}
|
||||||
|
|
||||||
fn state_data(&self, hash: &H256) -> Option<Bytes> {
|
fn state_data(&self, hash: &H256) -> Option<Bytes> {
|
||||||
self.state_db.lock().unwrap().state(hash)
|
self.state_db.lock().unwrap().state(hash)
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,9 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
/// See `BlockChain::tree_route`.
|
/// See `BlockChain::tree_route`.
|
||||||
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute>;
|
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute>;
|
||||||
|
|
||||||
|
/// Get all possible uncle hashes for a block.
|
||||||
|
fn find_uncles(&self, hash: &H256) -> Option<Vec<H256>>;
|
||||||
|
|
||||||
/// Get latest state node
|
/// Get latest state node
|
||||||
fn state_data(&self, hash: &H256) -> Option<Bytes>;
|
fn state_data(&self, hash: &H256) -> Option<Bytes>;
|
||||||
|
|
||||||
|
@ -348,6 +348,10 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_uncles(&self, _hash: &H256) -> Option<Vec<H256>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: returns just hashes instead of node state rlp(?)
|
// TODO: returns just hashes instead of node state rlp(?)
|
||||||
fn state_data(&self, hash: &H256) -> Option<Bytes> {
|
fn state_data(&self, hash: &H256) -> Option<Bytes> {
|
||||||
// starts with 'f' ?
|
// starts with 'f' ?
|
||||||
|
@ -252,7 +252,7 @@ impl ChainSync {
|
|||||||
let chain = chain.chain_info();
|
let chain = chain.chain_info();
|
||||||
let mut sync = ChainSync {
|
let mut sync = ChainSync {
|
||||||
state: SyncState::ChainHead,
|
state: SyncState::ChainHead,
|
||||||
starting_block: 0,
|
starting_block: chain.best_block_number,
|
||||||
highest_block: None,
|
highest_block: None,
|
||||||
last_imported_block: chain.best_block_number,
|
last_imported_block: chain.best_block_number,
|
||||||
last_imported_hash: chain.best_block_hash,
|
last_imported_hash: chain.best_block_hash,
|
||||||
@ -278,7 +278,7 @@ impl ChainSync {
|
|||||||
network_id: self.network_id,
|
network_id: self.network_id,
|
||||||
start_block_number: self.starting_block,
|
start_block_number: self.starting_block,
|
||||||
last_imported_block_number: Some(self.last_imported_block),
|
last_imported_block_number: Some(self.last_imported_block),
|
||||||
highest_block_number: self.highest_block,
|
highest_block_number: self.highest_block.map(|n| max(n, self.last_imported_block)),
|
||||||
blocks_received: if self.last_imported_block > self.starting_block { self.last_imported_block - self.starting_block } else { 0 },
|
blocks_received: if self.last_imported_block > self.starting_block { self.last_imported_block - self.starting_block } else { 0 },
|
||||||
blocks_total: match self.highest_block { Some(x) if x > self.starting_block => x - self.starting_block, _ => 0 },
|
blocks_total: match self.highest_block { Some(x) if x > self.starting_block => x - self.starting_block, _ => 0 },
|
||||||
num_peers: self.peers.len(),
|
num_peers: self.peers.len(),
|
||||||
@ -1114,11 +1114,14 @@ impl ChainSync {
|
|||||||
fn create_new_hashes_rlp(chain: &BlockChainClient, from: &H256, to: &H256) -> Option<Bytes> {
|
fn create_new_hashes_rlp(chain: &BlockChainClient, from: &H256, to: &H256) -> Option<Bytes> {
|
||||||
match chain.tree_route(from, to) {
|
match chain.tree_route(from, to) {
|
||||||
Some(route) => {
|
Some(route) => {
|
||||||
|
let uncles = chain.find_uncles(from).unwrap_or_else(Vec::new);
|
||||||
match route.blocks.len() {
|
match route.blocks.len() {
|
||||||
0 => None,
|
0 => None,
|
||||||
_ => {
|
_ => {
|
||||||
let mut rlp_stream = RlpStream::new_list(route.blocks.len());
|
let mut blocks = route.blocks;
|
||||||
for block_hash in route.blocks {
|
blocks.extend(uncles);
|
||||||
|
let mut rlp_stream = RlpStream::new_list(blocks.len());
|
||||||
|
for block_hash in blocks {
|
||||||
let mut hash_rlp = RlpStream::new_list(2);
|
let mut hash_rlp = RlpStream::new_list(2);
|
||||||
let difficulty = chain.block_total_difficulty(BlockID::Hash(block_hash.clone())).expect("Malformed block without a difficulty on the chain!");
|
let difficulty = chain.block_total_difficulty(BlockID::Hash(block_hash.clone())).expect("Malformed block without a difficulty on the chain!");
|
||||||
hash_rlp.append(&block_hash);
|
hash_rlp.append(&block_hash);
|
||||||
|
Loading…
Reference in New Issue
Block a user