warn if no max_head_block_age

This commit is contained in:
Bryan Stitt 2023-06-17 09:19:05 -07:00
parent 3b9314a76f
commit bf13e86a04
7 changed files with 27 additions and 16 deletions

View File

@ -23,6 +23,8 @@ min_sum_soft_limit = 1_000
# only mark a block as the head block if the number of servers with it is great than or equal to min_synced_rpcs # only mark a block as the head block if the number of servers with it is great than or equal to min_synced_rpcs
min_synced_rpcs = 1 min_synced_rpcs = 1
max_head_block_age = 30
# redis is optional. it is used for rate limits set by `hard_limit` # redis is optional. it is used for rate limits set by `hard_limit`
# TODO: how do we find the optimal redis_max_connections? too high actually ends up being slower # TODO: how do we find the optimal redis_max_connections? too high actually ends up being slower
volatile_redis_max_connections = 20 volatile_redis_max_connections = 20

View File

@ -28,6 +28,9 @@ min_sum_soft_limit = 2_000
# only mark a block as the head block if the number of servers with it is great than or equal to min_synced_rpcs # only mark a block as the head block if the number of servers with it is great than or equal to min_synced_rpcs
min_synced_rpcs = 2 min_synced_rpcs = 2
# don't serve requests if the best known block is >60 seconds old
max_head_block_age = 60
# redis is optional. it is used for rate limits set by `hard_limit` # redis is optional. it is used for rate limits set by `hard_limit`
# TODO: how do we find the optimal redis_max_connections? too high actually ends up being slower # TODO: how do we find the optimal redis_max_connections? too high actually ends up being slower
volatile_redis_max_connections = 300 volatile_redis_max_connections = 300

View File

@ -196,6 +196,10 @@ impl Web3ProxyApp {
); );
} }
if top_config.app.max_head_block_age.is_none() {
warn!("no max_head_block_age. stale data could be served!");
}
if !top_config.extra.is_empty() { if !top_config.extra.is_empty() {
warn!( warn!(
"unknown TopConfig fields!: {:?}", "unknown TopConfig fields!: {:?}",
@ -501,7 +505,7 @@ impl Web3ProxyApp {
let (balanced_rpcs, balanced_handle, consensus_connections_watcher) = Web3Rpcs::spawn( let (balanced_rpcs, balanced_handle, consensus_connections_watcher) = Web3Rpcs::spawn(
db_conn.clone(), db_conn.clone(),
top_config.app.max_block_age, top_config.app.max_head_block_age,
top_config.app.max_block_lag, top_config.app.max_block_lag,
top_config.app.min_synced_rpcs, top_config.app.min_synced_rpcs,
top_config.app.min_sum_soft_limit, top_config.app.min_sum_soft_limit,
@ -526,7 +530,7 @@ impl Web3ProxyApp {
// let (private_rpcs, private_rpcs_handle) = Web3Rpcs::spawn( // let (private_rpcs, private_rpcs_handle) = Web3Rpcs::spawn(
let (private_rpcs, private_handle, _) = Web3Rpcs::spawn( let (private_rpcs, private_handle, _) = Web3Rpcs::spawn(
db_conn.clone(), db_conn.clone(),
// private rpcs don't get subscriptions, so no need for max_block_age or max_block_lag // private rpcs don't get subscriptions, so no need for max_head_block_age or max_block_lag
None, None,
None, None,
0, 0,
@ -558,7 +562,7 @@ impl Web3ProxyApp {
// TODO: do something with the spawn handle // TODO: do something with the spawn handle
let (bundler_4337_rpcs, bundler_4337_rpcs_handle, _) = Web3Rpcs::spawn( let (bundler_4337_rpcs, bundler_4337_rpcs_handle, _) = Web3Rpcs::spawn(
db_conn.clone(), db_conn.clone(),
// bundler_4337_rpcs don't get subscriptions, so no need for max_block_age or max_block_lag // bundler_4337_rpcs don't get subscriptions, so no need for max_head_block_age or max_block_lag
None, None,
None, None,
0, 0,

View File

@ -121,7 +121,7 @@ pub struct AppConfig {
pub login_domain: Option<String>, pub login_domain: Option<String>,
/// do not serve any requests if the best known block is older than this many seconds. /// do not serve any requests if the best known block is older than this many seconds.
pub max_block_age: Option<u64>, pub max_head_block_age: Option<u64>,
/// do not serve any requests if the best known block is behind the best known block by more than this many blocks. /// do not serve any requests if the best known block is behind the best known block by more than this many blocks.
pub max_block_lag: Option<U64>, pub max_block_lag: Option<U64>,

View File

@ -401,7 +401,8 @@ impl Web3Rpcs {
// Geth's subscriptions have the same potential for skipping blocks. // Geth's subscriptions have the same potential for skipping blocks.
pending_tx_sender: Option<broadcast::Sender<TxStatus>>, pending_tx_sender: Option<broadcast::Sender<TxStatus>>,
) -> Web3ProxyResult<()> { ) -> Web3ProxyResult<()> {
let mut connection_heads = ConsensusFinder::new(self.max_block_age, self.max_block_lag); let mut connection_heads =
ConsensusFinder::new(self.max_head_block_age, self.max_block_lag);
loop { loop {
match block_receiver.recv_async().await { match block_receiver.recv_async().await {

View File

@ -339,7 +339,7 @@ type FirstSeenCache = Cache<H256, Instant>;
pub struct ConsensusFinder { pub struct ConsensusFinder {
rpc_heads: HashMap<Arc<Web3Rpc>, Web3ProxyBlock>, rpc_heads: HashMap<Arc<Web3Rpc>, Web3ProxyBlock>,
/// never serve blocks that are too old /// never serve blocks that are too old
max_block_age: Option<u64>, max_head_block_age: Option<u64>,
/// tier 0 will be prefered as long as the distance between it and the other tiers is <= max_tier_lag /// tier 0 will be prefered as long as the distance between it and the other tiers is <= max_tier_lag
max_block_lag: Option<U64>, max_block_lag: Option<U64>,
/// Block Hash -> First Seen Instant. used to track rpc.head_latency. The same cache should be shared between all ConnectionsGroups /// Block Hash -> First Seen Instant. used to track rpc.head_latency. The same cache should be shared between all ConnectionsGroups
@ -347,7 +347,7 @@ pub struct ConsensusFinder {
} }
impl ConsensusFinder { impl ConsensusFinder {
pub fn new(max_block_age: Option<u64>, max_block_lag: Option<U64>) -> Self { pub fn new(max_head_block_age: Option<u64>, max_block_lag: Option<U64>) -> Self {
// TODO: what's a good capacity for this? it shouldn't need to be very large // TODO: what's a good capacity for this? it shouldn't need to be very large
let first_seen = Cache::new(16); let first_seen = Cache::new(16);
@ -355,7 +355,7 @@ impl ConsensusFinder {
Self { Self {
rpc_heads, rpc_heads,
max_block_age, max_head_block_age,
max_block_lag, max_block_lag,
first_seen, first_seen,
} }
@ -406,7 +406,7 @@ impl ConsensusFinder {
.await .await
.web3_context("failed caching block")?; .web3_context("failed caching block")?;
if let Some(max_age) = self.max_block_age { if let Some(max_age) = self.max_head_block_age {
if rpc_head_block.age() > max_age { if rpc_head_block.age() > max_age {
trace!("rpc_head_block from {} is too old! {}", rpc, rpc_head_block); trace!("rpc_head_block from {} is too old! {}", rpc, rpc_head_block);
return Ok(self.remove(&rpc).is_some()); return Ok(self.remove(&rpc).is_some());
@ -536,6 +536,7 @@ impl ConsensusFinder {
trace!("lowest_block_number: {}", lowest_block.number()); trace!("lowest_block_number: {}", lowest_block.number());
// TODO: move this default. should be in config, not here
let max_lag_block_number = let max_lag_block_number =
highest_block_number.saturating_sub(self.max_block_lag.unwrap_or_else(|| U64::from(5))); highest_block_number.saturating_sub(self.max_block_lag.unwrap_or_else(|| U64::from(5)));

View File

@ -68,7 +68,7 @@ pub struct Web3Rpcs {
/// how far behind the highest known block height we can be before we stop serving requests /// how far behind the highest known block height we can be before we stop serving requests
pub(super) max_block_lag: Option<U64>, pub(super) max_block_lag: Option<U64>,
/// how old our consensus head block we can be before we stop serving requests /// how old our consensus head block we can be before we stop serving requests
pub(super) max_block_age: Option<u64>, pub(super) max_head_block_age: Option<u64>,
} }
impl Web3Rpcs { impl Web3Rpcs {
@ -76,7 +76,7 @@ impl Web3Rpcs {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub async fn spawn( pub async fn spawn(
db_conn: Option<DatabaseConnection>, db_conn: Option<DatabaseConnection>,
max_block_age: Option<u64>, max_head_block_age: Option<u64>,
max_block_lag: Option<U64>, max_block_lag: Option<U64>,
min_head_rpcs: usize, min_head_rpcs: usize,
min_sum_soft_limit: u32, min_sum_soft_limit: u32,
@ -120,7 +120,7 @@ impl Web3Rpcs {
blocks_by_hash, blocks_by_hash,
blocks_by_number, blocks_by_number,
by_name, by_name,
max_block_age, max_head_block_age,
max_block_lag, max_block_lag,
min_synced_rpcs: min_head_rpcs, min_synced_rpcs: min_head_rpcs,
min_sum_soft_limit, min_sum_soft_limit,
@ -1526,8 +1526,8 @@ mod tests {
blocks_by_number: CacheBuilder::new(100) blocks_by_number: CacheBuilder::new(100)
.time_to_live(Duration::from_secs(60)) .time_to_live(Duration::from_secs(60))
.build(), .build(),
// TODO: test max_block_age? // TODO: test max_head_block_age?
max_block_age: None, max_head_block_age: None,
// TODO: test max_block_lag? // TODO: test max_block_lag?
max_block_lag: None, max_block_lag: None,
min_synced_rpcs: 1, min_synced_rpcs: 1,
@ -1808,7 +1808,7 @@ mod tests {
.build(), .build(),
min_synced_rpcs: 1, min_synced_rpcs: 1,
min_sum_soft_limit: 4_000, min_sum_soft_limit: 4_000,
max_block_age: None, max_head_block_age: None,
max_block_lag: None, max_block_lag: None,
}; };
@ -1988,7 +1988,7 @@ mod tests {
blocks_by_number: Cache::new(10_000), blocks_by_number: Cache::new(10_000),
min_synced_rpcs: 1, min_synced_rpcs: 1,
min_sum_soft_limit: 1_000, min_sum_soft_limit: 1_000,
max_block_age: None, max_head_block_age: None,
max_block_lag: None, max_block_lag: None,
}; };