Skip to content

Commit cc5a1d5

Browse files
viquezclaudiojsdanielh
authored andcommitted
Fix for interlink in block inclusion proof
1 parent 6457c32 commit cc5a1d5

2 files changed

Lines changed: 26 additions & 2 deletions

File tree

primitives/block/src/block_proof.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ impl BlockInclusionProof {
7979
election_head.block_number(),
8080
);
8181

82-
// The election head might already have an interlink or prev_election_head link to the target
82+
// An empty proof is only valid if the election head already references the target directly.
8383
if hops.is_empty() {
84-
return true;
84+
return Self::references_block(election_head, target);
8585
}
8686

8787
// Check that the proof contains all needed hops
@@ -129,4 +129,15 @@ impl BlockInclusionProof {
129129
}
130130
true
131131
}
132+
133+
fn references_block(block: &MacroBlock, target: &MacroBlock) -> bool {
134+
let target_hash = target.hash();
135+
136+
block.header.parent_election_hash == target_hash
137+
|| block
138+
.header
139+
.interlink
140+
.as_ref()
141+
.is_some_and(|interlink| interlink.contains(&target_hash))
142+
}
132143
}

primitives/block/tests/block_proof.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::collections::HashMap;
22

33
use nimiq_block::{BlockInclusionProof, MacroBlock, MacroHeader};
4+
use nimiq_hash::Hash;
45
use nimiq_primitives::policy::Policy;
56

67
#[test]
@@ -85,6 +86,18 @@ fn test_is_block_proven() {
8586
let block_proof = BlockInclusionProof { proof: vec![] };
8687
assert!(block_proof.is_block_proven(&blocks[&10], &blocks[&9]));
8788

89+
// Current election head: 10, target: forged 9. Claimed proof []
90+
let mut forged_parent_target = blocks[&9].clone();
91+
forged_parent_target.header.history_root = "forged-parent-target".hash();
92+
let block_proof = BlockInclusionProof { proof: vec![] };
93+
assert!(!block_proof.is_block_proven(&blocks[&10], &forged_parent_target));
94+
95+
// Current election head: 10, target: forged 8. Claimed proof []
96+
let mut forged_interlink_target = blocks[&8].clone();
97+
forged_interlink_target.header.history_root = "forged-interlink-target".hash();
98+
let block_proof = BlockInclusionProof { proof: vec![] };
99+
assert!(!block_proof.is_block_proven(&blocks[&10], &forged_interlink_target));
100+
88101
// Current election head: 22, target: 1. Claimed proof [17 (wrong), 8, 4, 2]
89102
let block_proof = BlockInclusionProof {
90103
proof: vec![

0 commit comments

Comments
 (0)