Stop awaiting the previous block in the block verifier
Instead, the state should cache blocks until the previous block has been committed.
This commit is contained in:
parent
8463b705c8
commit
7f2bebb97d
|
@ -22,9 +22,7 @@ use std::{
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
time::Duration,
|
|
||||||
};
|
};
|
||||||
use tokio::time;
|
|
||||||
use tower::{buffer::Buffer, Service, ServiceExt};
|
use tower::{buffer::Buffer, Service, ServiceExt};
|
||||||
|
|
||||||
use zebra_chain::block::{self, Block};
|
use zebra_chain::block::{self, Block};
|
||||||
|
@ -125,42 +123,6 @@ where
|
||||||
|
|
||||||
// TODO: context-free header verification: merkle root
|
// TODO: context-free header verification: merkle root
|
||||||
|
|
||||||
// As a temporary solution for chain gaps, wait for the previous block,
|
|
||||||
// and check its height.
|
|
||||||
//
|
|
||||||
// TODO: replace this check with the contextual verification RFC design
|
|
||||||
//
|
|
||||||
// Skip contextual checks for the genesis block
|
|
||||||
let previous_block_hash = block.header.previous_block_hash;
|
|
||||||
if previous_block_hash != crate::parameters::GENESIS_PREVIOUS_BLOCK_HASH {
|
|
||||||
if height == block::Height(0) {
|
|
||||||
Err(format!("invalid block {:?}: height is 0, but previous block hash {:?} is not null",
|
|
||||||
hash,
|
|
||||||
previous_block_hash))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let expected_height = block::Height(height.0 - 1);
|
|
||||||
tracing::trace!(?expected_height, ?previous_block_hash, "Waiting for previous block");
|
|
||||||
metrics::gauge!("block.waiting.block.height", expected_height.0 as i64);
|
|
||||||
metrics::counter!("block.waiting.count", 1);
|
|
||||||
|
|
||||||
let previous_block = BlockVerifier::await_block(
|
|
||||||
&mut state_service,
|
|
||||||
previous_block_hash,
|
|
||||||
expected_height,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let previous_height = previous_block.coinbase_height().unwrap();
|
|
||||||
if previous_height != expected_height {
|
|
||||||
Err(format!("invalid block height {:?} for {:?}: must be 1 more than the previous block height {:?} in {:?}",
|
|
||||||
height,
|
|
||||||
hash,
|
|
||||||
previous_height,
|
|
||||||
previous_block_hash))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tracing::trace!("verified block");
|
tracing::trace!("verified block");
|
||||||
metrics::gauge!(
|
metrics::gauge!(
|
||||||
"block.verified.block.height",
|
"block.verified.block.height",
|
||||||
|
@ -168,9 +130,8 @@ where
|
||||||
);
|
);
|
||||||
metrics::counter!("block.verified.block.count", 1);
|
metrics::counter!("block.verified.block.count", 1);
|
||||||
|
|
||||||
// We need to add the block after the previous block is in the state,
|
// Commit the block in the future - the state will handle out of
|
||||||
// and before this future returns. Otherwise, blocks could be
|
// order blocks.
|
||||||
// committed out of order.
|
|
||||||
let ready_state = state_service
|
let ready_state = state_service
|
||||||
.ready_and()
|
.ready_and()
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -221,27 +182,6 @@ where
|
||||||
|
|
||||||
Ok(block)
|
Ok(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wait until a block with `hash` is in `state_service`.
|
|
||||||
///
|
|
||||||
/// Returns an error if `state_service.poll_ready` errors.
|
|
||||||
async fn await_block(
|
|
||||||
state_service: &mut S,
|
|
||||||
hash: block::Hash,
|
|
||||||
height: block::Height,
|
|
||||||
) -> Result<Arc<Block>, Report> {
|
|
||||||
loop {
|
|
||||||
match BlockVerifier::get_block(state_service, hash).await? {
|
|
||||||
Some(block) => return Ok(block),
|
|
||||||
// Busy-waiting is only a temporary solution to waiting for blocks.
|
|
||||||
// Replace with the contextual verification RFC design
|
|
||||||
None => {
|
|
||||||
tracing::debug!(?height, ?hash, "Waiting for state to have block");
|
|
||||||
time::delay_for(Duration::from_millis(50)).await
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a block verification service, using the provided state service.
|
/// Return a block verification service, using the provided state service.
|
||||||
|
|
Loading…
Reference in New Issue