state: Move block header hashing to block_index

Only hash block headers in the lowest-level block index code.

This design has a few benefits:
  - failures are obvious, because the hash is not available,
  - get_tip() returns a smaller object,
  - we avoid re-hashing block headers multiple times.

These efficiency changes may be needed to support chain reorganisations,
multiple tips, and heavy query loads.
This commit is contained in:
teor 2020-06-12 15:04:52 +10:00 committed by Henry de Valence
parent 26a58b23de
commit 334329f38a
2 changed files with 8 additions and 7 deletions

View File

@ -30,8 +30,10 @@ impl Service<Request> for ZebraState {
fn call(&mut self, req: Request) -> Self::Future {
match req {
Request::AddBlock { block } => {
let hash = block.as_ref().into();
let result = self.index.insert(block).map(|_| Response::Added { hash });
let result = self
.index
.insert(block)
.map(|hash| Response::Added { hash });
async { result }.boxed()
}
@ -48,7 +50,6 @@ impl Service<Request> for ZebraState {
let result = self
.index
.get_tip()
.map(|block| block.as_ref().into())
.map(|hash| Response::Tip { hash })
.ok_or_else(|| "zebra-state contains no blocks".into());

View File

@ -17,7 +17,7 @@ impl BlockIndex {
pub(super) fn insert(
&mut self,
block: impl Into<Arc<Block>>,
) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
) -> Result<BlockHeaderHash, Box<dyn Error + Send + Sync + 'static>> {
let block = block.into();
let hash = block.as_ref().into();
let height = block.coinbase_height().unwrap();
@ -26,7 +26,7 @@ impl BlockIndex {
Entry::Vacant(entry) => {
let _ = entry.insert(block.clone());
let _ = self.by_hash.insert(hash, block);
Ok(())
Ok(hash)
}
Entry::Occupied(_) => Err("forks in the chain aren't supported yet")?,
}
@ -40,12 +40,12 @@ impl BlockIndex {
.cloned()
}
pub(super) fn get_tip(&self) -> Option<Arc<Block>> {
pub(super) fn get_tip(&self) -> Option<BlockHeaderHash> {
self.by_height
.iter()
.next_back()
.map(|(_key, value)| value)
.cloned()
.map(|block| block.as_ref().into())
}
}