Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Fix chain API ancestors look-up at genesis block #4560

Merged
merged 1 commit into from
Dec 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion node/core/chain-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ where
Ok(None) => None,
Ok(Some(header)) => {
// stop at the genesis header.
if header.number == 1 {
if header.number == 0 {
None
} else {
hash = header.parent_hash;
Expand Down
33 changes: 32 additions & 1 deletion node/core/chain-api/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct TestClient {
headers: BTreeMap<Hash, Header>,
}

const GENESIS: Hash = Hash::repeat_byte(0xAA);
const ONE: Hash = Hash::repeat_byte(0x01);
const TWO: Hash = Hash::repeat_byte(0x02);
const THREE: Hash = Hash::repeat_byte(0x03);
Expand All @@ -38,6 +39,7 @@ impl Default for TestClient {
fn default() -> Self {
Self {
blocks: maplit::btreemap! {
GENESIS => 0,
ONE => 1,
TWO => 2,
THREE => 3,
Expand All @@ -54,6 +56,16 @@ impl Default for TestClient {
3 => THREE,
},
headers: maplit::btreemap! {
GENESIS => Header {
parent_hash: Hash::zero(), // Dummy parent with zero hash.
number: 0,
..default_header()
},
ONE => Header {
parent_hash: GENESIS,
number: 1,
..default_header()
},
TWO => Header {
parent_hash: ONE,
number: 2,
Expand Down Expand Up @@ -298,8 +310,9 @@ fn request_ancestors() {
msg: ChainApiMessage::Ancestors { hash: THREE, k: 4, response_channel: tx },
})
.await;
assert_eq!(rx.await.unwrap().unwrap(), vec![TWO, ONE]);
assert_eq!(rx.await.unwrap().unwrap(), vec![TWO, ONE, GENESIS]);

// Limit the number of ancestors.
let (tx, rx) = oneshot::channel();
sender
.send(FromOverseer::Communication {
Expand All @@ -308,6 +321,24 @@ fn request_ancestors() {
.await;
assert_eq!(rx.await.unwrap().unwrap(), vec![ONE]);

// Ancestor of block #1 is returned.
let (tx, rx) = oneshot::channel();
sender
.send(FromOverseer::Communication {
msg: ChainApiMessage::Ancestors { hash: ONE, k: 10, response_channel: tx },
})
.await;
assert_eq!(rx.await.unwrap().unwrap(), vec![GENESIS]);

// No ancestors of genesis block.
let (tx, rx) = oneshot::channel();
sender
.send(FromOverseer::Communication {
msg: ChainApiMessage::Ancestors { hash: GENESIS, k: 10, response_channel: tx },
})
.await;
assert_eq!(rx.await.unwrap().unwrap(), Vec::new());

let (tx, rx) = oneshot::channel();
sender
.send(FromOverseer::Communication {
Expand Down
3 changes: 2 additions & 1 deletion node/subsystem-types/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,8 @@ pub enum ChainApiMessage {
/// Request the `k` ancestors block hashes of a block with the given hash.
/// The response channel may return a `Vec` of size up to `k`
/// filled with ancestors hashes with the following order:
/// `parent`, `grandparent`, ...
/// `parent`, `grandparent`, ... up to the hash of genesis block
/// with number 0, including it.
Ancestors {
/// The hash of the block in question.
hash: Hash,
Expand Down