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:
parent
26a58b23de
commit
334329f38a
|
|
@ -30,8 +30,10 @@ impl Service<Request> for ZebraState {
|
||||||
fn call(&mut self, req: Request) -> Self::Future {
|
fn call(&mut self, req: Request) -> Self::Future {
|
||||||
match req {
|
match req {
|
||||||
Request::AddBlock { block } => {
|
Request::AddBlock { block } => {
|
||||||
let hash = block.as_ref().into();
|
let result = self
|
||||||
let result = self.index.insert(block).map(|_| Response::Added { hash });
|
.index
|
||||||
|
.insert(block)
|
||||||
|
.map(|hash| Response::Added { hash });
|
||||||
|
|
||||||
async { result }.boxed()
|
async { result }.boxed()
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +50,6 @@ impl Service<Request> for ZebraState {
|
||||||
let result = self
|
let result = self
|
||||||
.index
|
.index
|
||||||
.get_tip()
|
.get_tip()
|
||||||
.map(|block| block.as_ref().into())
|
|
||||||
.map(|hash| Response::Tip { hash })
|
.map(|hash| Response::Tip { hash })
|
||||||
.ok_or_else(|| "zebra-state contains no blocks".into());
|
.ok_or_else(|| "zebra-state contains no blocks".into());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ impl BlockIndex {
|
||||||
pub(super) fn insert(
|
pub(super) fn insert(
|
||||||
&mut self,
|
&mut self,
|
||||||
block: impl Into<Arc<Block>>,
|
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 block = block.into();
|
||||||
let hash = block.as_ref().into();
|
let hash = block.as_ref().into();
|
||||||
let height = block.coinbase_height().unwrap();
|
let height = block.coinbase_height().unwrap();
|
||||||
|
|
@ -26,7 +26,7 @@ impl BlockIndex {
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => {
|
||||||
let _ = entry.insert(block.clone());
|
let _ = entry.insert(block.clone());
|
||||||
let _ = self.by_hash.insert(hash, block);
|
let _ = self.by_hash.insert(hash, block);
|
||||||
Ok(())
|
Ok(hash)
|
||||||
}
|
}
|
||||||
Entry::Occupied(_) => Err("forks in the chain aren't supported yet")?,
|
Entry::Occupied(_) => Err("forks in the chain aren't supported yet")?,
|
||||||
}
|
}
|
||||||
|
|
@ -40,12 +40,12 @@ impl BlockIndex {
|
||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_tip(&self) -> Option<Arc<Block>> {
|
pub(super) fn get_tip(&self) -> Option<BlockHeaderHash> {
|
||||||
self.by_height
|
self.by_height
|
||||||
.iter()
|
.iter()
|
||||||
.next_back()
|
.next_back()
|
||||||
.map(|(_key, value)| value)
|
.map(|(_key, value)| value)
|
||||||
.cloned()
|
.map(|block| block.as_ref().into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue