warn if no max_head_block_age
This commit is contained in:
parent
3b9314a76f
commit
bf13e86a04
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)));
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue