Skip to content

Commit 36ed9fa

Browse files
authored
A0-0000: Don't import unimportable blocks (#1959) (#1960)
# Description Our sync tried importing everything that was required. This was not a major issue before 15.1, since at worst the import failed and whatever, but with optimistic imports we gotta be relatively confident that the import will actually work. ## Type of change - Bug fix (non-breaking change which fixes an issue) # Checklist: - I have added tests - I have made corresponding changes to the existing documentation - I have created new documentation
1 parent f2a00c1 commit 36ed9fa

File tree

3 files changed

+64
-4
lines changed

3 files changed

+64
-4
lines changed

bin/node/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "aleph-node"
3-
version = "15.1.0"
3+
version = "15.2.0"
44
description = "Aleph node binary"
55
build = "build.rs"
66
license = "GPL-3.0-or-later"

finality-aleph/src/sync/forest/mod.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,11 +608,29 @@ where
608608
}
609609
}
610610

611-
pub fn start_import(&mut self, id: &BlockId) {
611+
/// Start an import of a block. Returns whether this is possible, i.e. the parent block is
612+
/// imported.
613+
pub fn start_import(&mut self, id: &BlockId) -> bool {
614+
let parent_id = match self.get(id) {
615+
VertexHandle::Candidate(vertex) => vertex.vertex.parent(),
616+
_ => return false,
617+
};
618+
let parent_id = match parent_id {
619+
Some(parent_id) => parent_id,
620+
None => return false,
621+
};
622+
// At this point this is equivalent to being imported, as we never get here for blocks that
623+
// are below minimal.
624+
if !self.skippable(&parent_id) {
625+
return false;
626+
}
612627
use VertexHandleMut::Candidate;
613628
if let Candidate(mut vertex) = self.get_mut(id) {
614629
vertex.get_mut().vertex.start_import();
630+
return true;
615631
}
632+
// This should never happen in practice.
633+
false
616634
}
617635

618636
fn know_most(&self, id: &BlockId) -> HashSet<I> {
@@ -1007,6 +1025,16 @@ mod tests {
10071025
));
10081026
}
10091027

1028+
#[test]
1029+
fn accepts_first_import() {
1030+
let (initial_header, mut forest) = setup();
1031+
let child = initial_header.random_child();
1032+
assert!(forest
1033+
.update_header(&child, None, true)
1034+
.expect("header was correct"));
1035+
assert!(forest.start_import(&child.id()));
1036+
}
1037+
10101038
#[test]
10111039
fn accepts_first_body() {
10121040
let (initial_header, mut forest) = setup();
@@ -1019,6 +1047,17 @@ mod tests {
10191047
assert_eq!(forest.extension_request(), Noop);
10201048
}
10211049

1050+
#[test]
1051+
fn rejects_import_when_parent_unimported() {
1052+
let (initial_header, mut forest) = setup();
1053+
let child = initial_header.random_child();
1054+
let grandchild = child.random_child();
1055+
assert!(forest
1056+
.update_header(&child, None, false)
1057+
.expect("header was correct"));
1058+
assert!(!forest.start_import(&grandchild.id()));
1059+
}
1060+
10221061
#[test]
10231062
fn rejects_body_when_parent_unimported() {
10241063
let (initial_header, mut forest) = setup();

finality-aleph/src/sync/handler/mod.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,8 +570,15 @@ where
570570
}),
571571
);
572572
}
573-
last_imported = Some(b.header().id());
574-
self.forest.start_import(&b.header().id());
573+
let block_id = b.header().id();
574+
if !self.forest.start_import(&block_id) {
575+
return (
576+
new_highest,
577+
equivocation_proofs,
578+
Some(Error::BlockNotImportable(block_id)),
579+
);
580+
}
581+
last_imported = Some(block_id);
575582
self.block_importer.import_block(b, false);
576583
}
577584
}
@@ -2566,6 +2573,20 @@ mod tests {
25662573
);
25672574
}
25682575

2576+
#[tokio::test]
2577+
async fn rejects_parentless_block() {
2578+
let (mut handler, _backend, _notifier, genesis) = setup();
2579+
2580+
// Create 2 new blocks and make the handler aware of them.
2581+
let mut branch = grow_light_branch(&mut handler, &genesis, 2, 0);
2582+
2583+
// Give only the latter to handler.
2584+
let parentless_block = MockBlock::new(branch.pop().expect("just created"), true);
2585+
let (_, _, e) =
2586+
handler.handle_request_response(vec![ResponseItem::Block(parentless_block)], 1);
2587+
assert!(matches!(e, Some(Error::BlockNotImportable(_))));
2588+
}
2589+
25692590
#[tokio::test]
25702591
async fn handles_wide_fork_scenario() {
25712592
let (mut handler, mut backend, mut notifier, genesis) = setup();

0 commit comments

Comments
 (0)