Skip to content
Snippets Groups Projects
Commit cab8fb5d authored by Arkadiy Paronyan's avatar Arkadiy Paronyan Committed by Bastian Köcher
Browse files

Fixed uncle pruning (#3491)

* Fixed uncle pruning

* Version bump
parent 10b032bb
No related merge requests found
......@@ -79,8 +79,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// and set impl_version to equal spec_version. If only runtime
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 152,
impl_version: 152,
spec_version: 153,
impl_version: 153,
apis: RUNTIME_API_VERSIONS,
};
......
......@@ -27,7 +27,7 @@ use srml_support::traits::{FindAuthor, VerifySeal, Get};
use srml_support::dispatch::Result as DispatchResult;
use codec::{Encode, Decode};
use system::ensure_none;
use sr_primitives::traits::{SimpleArithmetic, Header as HeaderT, One, Zero};
use sr_primitives::traits::{Header as HeaderT, One, Zero};
use sr_primitives::weights::SimpleDispatchInfo;
use inherents::{
RuntimeString, InherentIdentifier, ProvideInherent,
......@@ -236,29 +236,14 @@ decl_storage! {
}
}
fn prune_old_uncles<BlockNumber, Hash, Author>(
minimum_height: BlockNumber,
uncles: &mut Vec<UncleEntryItem<BlockNumber, Hash, Author>>
) where BlockNumber: SimpleArithmetic {
let prune_entries = uncles.iter().take_while(|item| match item {
UncleEntryItem::Uncle(_, _) => true,
UncleEntryItem::InclusionHeight(height) => height < &minimum_height,
});
let prune_index = prune_entries.count();
let _ = uncles.drain(..prune_index);
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn on_initialize(now: T::BlockNumber) {
let uncle_generations = T::UncleGenerations::get();
let mut uncles = <Self as Store>::Uncles::get();
// prune uncles that are older than the allowed number of generations.
if uncle_generations <= now {
let minimum_height = now - uncle_generations;
prune_old_uncles(minimum_height, &mut uncles)
Self::prune_old_uncles(minimum_height)
}
<Self as Store>::DidSetUncles::put(false);
......@@ -387,6 +372,18 @@ impl<T: Trait> Module<T> {
// check uncle validity.
T::FilterUncle::filter_uncle(&uncle, accumulator)
}
fn prune_old_uncles(minimum_height: T::BlockNumber) {
let mut uncles = <Self as Store>::Uncles::get();
let prune_entries = uncles.iter().take_while(|item| match item {
UncleEntryItem::Uncle(_, _) => true,
UncleEntryItem::InclusionHeight(height) => height < &minimum_height,
});
let prune_index = prune_entries.count();
let _ = uncles.drain(..prune_index);
<Self as Store>::Uncles::put(uncles);
}
}
impl<T: Trait> ProvideInherent for Module<T> {
......@@ -569,15 +566,21 @@ mod tests {
#[test]
fn prune_old_uncles_works() {
use UncleEntryItem::*;
let mut uncles = vec![
InclusionHeight(1u32), Uncle((), Some(())), Uncle((), None), Uncle((), None),
InclusionHeight(2u32), Uncle((), None),
InclusionHeight(3u32), Uncle((), None),
];
prune_old_uncles(3, &mut uncles);
assert_eq!(uncles, vec![InclusionHeight(3), Uncle((), None)]);
with_externalities(&mut new_test_ext(), || {
let hash = Default::default();
let author = Default::default();
let uncles = vec![
InclusionHeight(1u64), Uncle(hash, Some(author)), Uncle(hash, None), Uncle(hash, None),
InclusionHeight(2u64), Uncle(hash, None),
InclusionHeight(3u64), Uncle(hash, None),
];
<Authorship as Store>::Uncles::put(uncles);
Authorship::prune_old_uncles(3);
let uncles = <Authorship as Store>::Uncles::get();
assert_eq!(uncles, vec![InclusionHeight(3u64), Uncle(hash, None)]);
})
}
#[test]
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment