Uncle inclusion in block authoring. Still need tests.
This commit is contained in:
parent
877270c35f
commit
039c0056bc
@ -503,41 +503,23 @@ impl BlockChain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a block's `parent`, find every block header which represents a valid uncle.
|
/// Given a block's `parent`, find every block header which represents a valid possible uncle.
|
||||||
pub fn find_uncle_headers(&self, parent: &H256) -> Option<Vec<Header>> {
|
pub fn find_uncle_headers(&self, parent: &H256, uncle_generations: usize) -> Option<Vec<Header>> {
|
||||||
let uncle_generations = 6usize;
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
// Find great-uncles (or second-cousins or whatever they are) -
|
|
||||||
// children of great-grandparents, great-great-grandparents... that were not already uncles in previous generations.
|
|
||||||
clog(StateDetail) << "Checking " << m_previousBlock.hash() << ", parent=" << m_previousBlock.parentHash();
|
|
||||||
h256Hash excluded = _bc.allKinFrom(m_currentBlock.parentHash(), 6);
|
|
||||||
auto p = m_previousBlock.parentHash();
|
|
||||||
for (unsigned gen = 0; gen < 6 && p != _bc.genesisHash() && unclesCount < 2; ++gen, p = _bc.details(p).parent)
|
|
||||||
{
|
|
||||||
auto us = _bc.details(p).children;
|
|
||||||
assert(us.size() >= 1); // must be at least 1 child of our grandparent - it's our own parent!
|
|
||||||
for (auto const& u: us)
|
|
||||||
if (!excluded.count(u)) // ignore any uncles/mainline blocks that we know about.
|
|
||||||
{
|
|
||||||
uncleBlockHeaders.push_back(_bc.info(u));
|
|
||||||
unclesData.appendRaw(_bc.headerData(u));
|
|
||||||
++unclesCount;
|
|
||||||
if (unclesCount == 2)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if !self.is_known(parent) { return None; }
|
if !self.is_known(parent) { return None; }
|
||||||
let mut _excluded = HashSet::new();
|
|
||||||
|
let mut excluded = HashSet::new();
|
||||||
for a in self.ancestry_iter(parent.clone()).unwrap().take(uncle_generations) {
|
for a in self.ancestry_iter(parent.clone()).unwrap().take(uncle_generations) {
|
||||||
for u in self.uncle_hashes(&a).unwrap().into_iter() {
|
excluded.extend(self.uncle_hashes(&a).unwrap().into_iter());
|
||||||
_excluded.insert(u);
|
excluded.insert(a);
|
||||||
}
|
}
|
||||||
_excluded.insert(a);
|
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
for a in self.ancestry_iter(parent.clone()).unwrap().skip(1).take(uncle_generations) {
|
||||||
|
ret.extend(self.block_details(&a).unwrap().children.iter()
|
||||||
|
.filter_map(|h| if excluded.contains(h) { None } else { self.block_header(h) })
|
||||||
|
);
|
||||||
}
|
}
|
||||||
None
|
Some(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get inserted block info which is critical to preapre extras updates.
|
/// Get inserted block info which is critical to preapre extras updates.
|
||||||
|
@ -457,7 +457,7 @@ impl Client {
|
|||||||
self.extra_data()
|
self.extra_data()
|
||||||
);
|
);
|
||||||
|
|
||||||
self.chain.read().unwrap().find_uncle_headers(&h).unwrap().into_iter().foreach(|h| { b.push_uncle(h).unwrap(); });
|
self.chain.read().unwrap().find_uncle_headers(&h, self.engine.deref().deref().maximum_uncle_age()).unwrap().into_iter().foreach(|h| { b.push_uncle(h).unwrap(); });
|
||||||
|
|
||||||
// TODO: push transactions.
|
// TODO: push transactions.
|
||||||
|
|
||||||
|
@ -47,6 +47,8 @@ pub trait Engine : Sync + Send {
|
|||||||
fn maximum_extra_data_size(&self) -> usize { decode(&self.spec().engine_params.get("maximumExtraDataSize").unwrap()) }
|
fn maximum_extra_data_size(&self) -> usize { decode(&self.spec().engine_params.get("maximumExtraDataSize").unwrap()) }
|
||||||
/// Maximum number of uncles a block is allowed to declare.
|
/// Maximum number of uncles a block is allowed to declare.
|
||||||
fn maximum_uncle_count(&self) -> usize { 2 }
|
fn maximum_uncle_count(&self) -> usize { 2 }
|
||||||
|
/// The number of generations back that uncles can be.
|
||||||
|
fn maximum_uncle_age(&self) -> usize { 6 }
|
||||||
/// The nonce with which accounts begin.
|
/// The nonce with which accounts begin.
|
||||||
fn account_start_nonce(&self) -> U256 { decode(&self.spec().engine_params.get("accountStartNonce").unwrap()) }
|
fn account_start_nonce(&self) -> U256 { decode(&self.spec().engine_params.get("accountStartNonce").unwrap()) }
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ pub fn verify_block_family<BC>(header: &Header, bytes: &[u8], engine: &Engine, b
|
|||||||
excluded.insert(header.hash());
|
excluded.insert(header.hash());
|
||||||
let mut hash = header.parent_hash.clone();
|
let mut hash = header.parent_hash.clone();
|
||||||
excluded.insert(hash.clone());
|
excluded.insert(hash.clone());
|
||||||
for _ in 0..6 {
|
for _ in 0..engine.maximum_uncle_age() {
|
||||||
match bc.block_details(&hash) {
|
match bc.block_details(&hash) {
|
||||||
Some(details) => {
|
Some(details) => {
|
||||||
excluded.insert(details.parent.clone());
|
excluded.insert(details.parent.clone());
|
||||||
@ -121,7 +121,7 @@ pub fn verify_block_family<BC>(header: &Header, bytes: &[u8], engine: &Engine, b
|
|||||||
// (8 Invalid)
|
// (8 Invalid)
|
||||||
|
|
||||||
let depth = if header.number > uncle.number { header.number - uncle.number } else { 0 };
|
let depth = if header.number > uncle.number { header.number - uncle.number } else { 0 };
|
||||||
if depth > 6 {
|
if depth > engine.maximum_uncle_age() as u64 {
|
||||||
return Err(From::from(BlockError::UncleTooOld(OutOfBounds { min: Some(header.number - depth), max: Some(header.number - 1), found: uncle.number })));
|
return Err(From::from(BlockError::UncleTooOld(OutOfBounds { min: Some(header.number - depth), max: Some(header.number - 1), found: uncle.number })));
|
||||||
}
|
}
|
||||||
else if depth < 1 {
|
else if depth < 1 {
|
||||||
|
Loading…
Reference in New Issue
Block a user