Skip to content

Commit

Permalink
feat: add is_canonical to block_info() RPC result
Browse files Browse the repository at this point in the history
Adds is_canonical field to the BlockInfo struct which is returned by
block_info() RPC.

perf: This requires a new call to
ArchivalState::block_belongs_to_canonical_chain() which may have to
search the path from block-digest to tip-digest.

So it potentially slows down block_info() RPC some.  However, this
enables the block-explorer the display the required info without a
2nd RPC call (per page request), so overall it should be a performance
win.
  • Loading branch information
dan-da committed Dec 18, 2024
1 parent 638926e commit 3995e39
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
6 changes: 5 additions & 1 deletion src/models/blockchain/block/block_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub struct BlockInfo {
pub fee: NeptuneCoins,
pub is_genesis: bool,
pub is_tip: bool,
pub is_canonical: bool,
}

// note: this is used by neptune-cli block-info command.
Expand All @@ -48,7 +49,8 @@ impl std::fmt::Display for BlockInfo {
+ &format!("mining_reward: {}\n", self.mining_reward)
+ &format!("fee: {}\n", self.fee)
+ &format!("is_genesis: {}\n", self.is_genesis)
+ &format!("is_tip: {}\n", self.is_tip);
+ &format!("is_tip: {}\n", self.is_tip)
+ &format!("is_canonical: {}\n", self.is_canonical);

write!(f, "{}", buf)
}
Expand All @@ -59,6 +61,7 @@ impl BlockInfo {
block: &Block,
genesis_digest: Digest,
tip_digest: Digest,
is_canonical: bool,
) -> Self {
let body = block.body();
let header = block.header();
Expand All @@ -76,6 +79,7 @@ impl BlockInfo {
mining_reward: crate::Block::block_subsidy(header.height),
is_genesis: digest == genesis_digest,
is_tip: digest == tip_digest,
is_canonical,
}
}
}
7 changes: 4 additions & 3 deletions src/models/blockchain/block/block_selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@ impl FromStr for BlockSelector {
}

impl BlockSelector {
/// returns Digest for this selector, if it exists. Returns the digest of
/// the block belonging to the canonical chain if multiple blocks with
/// same height is found.
/// returns canonical chain block Digest for this selector, if it exists.
///
/// note: if multiple blocks with same height are found only the digest
/// of the block belonging to canonical chain is returned.
pub async fn as_digest(&self, state: &GlobalState) -> Option<Digest> {
match self {
BlockSelector::Digest(d) => Some(*d),
Expand Down
18 changes: 17 additions & 1 deletion src/rpc_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -821,13 +821,19 @@ impl RPC for NeptuneRPCServer {

let state = self.state.lock_guard().await;
let digest = block_selector.as_digest(&state).await?;
let tip_digest = state.chain.light_state().hash();
let archival_state = state.chain.archival_state();

let block = archival_state.get_block(digest).await.unwrap()?;
let is_canonical = archival_state
.block_belongs_to_canonical_chain(digest, tip_digest)
.await;

Some(BlockInfo::from_block_and_digests(
&block,
archival_state.genesis_block().hash(),
state.chain.light_state().hash(),
tip_digest,
is_canonical,
))
}

Expand Down Expand Up @@ -2117,12 +2123,22 @@ mod rpc_server_tests {
global_state.chain.archival_state().genesis_block(),
genesis_hash,
tip_hash,
global_state
.chain
.archival_state()
.block_belongs_to_canonical_chain(genesis_hash, tip_hash)
.await,
);

let tip_block_info = BlockInfo::from_block_and_digests(
global_state.chain.light_state(),
genesis_hash,
tip_hash,
global_state
.chain
.archival_state()
.block_belongs_to_canonical_chain(tip_hash, tip_hash)
.await,
);

// should find genesis block by Genesis selector
Expand Down

0 comments on commit 3995e39

Please sign in to comment.