less function args. more owned data
This commit is contained in:
parent
723199076c
commit
be68a9babb
@ -40,8 +40,8 @@ pub struct Web3Rpcs {
|
|||||||
/// TODO: hopefully this not being an async lock will be okay. if you need it across awaits, clone the arc
|
/// TODO: hopefully this not being an async lock will be okay. if you need it across awaits, clone the arc
|
||||||
pub(crate) by_name: RwLock<HashMap<String, Arc<Web3Rpc>>>,
|
pub(crate) by_name: RwLock<HashMap<String, Arc<Web3Rpc>>>,
|
||||||
/// all providers with the same consensus head block. won't update if there is no `self.watch_head_block`
|
/// all providers with the same consensus head block. won't update if there is no `self.watch_head_block`
|
||||||
/// TODO: document that this is a watch sender and not a broadcast! if things get busy, blocks might get missed
|
|
||||||
/// TODO: why is watch_head_block in an Option, but this one isn't?
|
/// TODO: why is watch_head_block in an Option, but this one isn't?
|
||||||
|
/// TODO: document that this is a watch sender and not a broadcast! if things get busy, blocks might get missed
|
||||||
/// Geth's subscriptions have the same potential for skipping blocks.
|
/// Geth's subscriptions have the same potential for skipping blocks.
|
||||||
pub(crate) watch_ranked_rpcs: watch::Sender<Option<Arc<RankedRpcs>>>,
|
pub(crate) watch_ranked_rpcs: watch::Sender<Option<Arc<RankedRpcs>>>,
|
||||||
/// this head receiver makes it easy to wait until there is a new block
|
/// this head receiver makes it easy to wait until there is a new block
|
||||||
|
@ -46,7 +46,13 @@ pub struct Web3Rpc {
|
|||||||
pub block_interval: Duration,
|
pub block_interval: Duration,
|
||||||
pub display_name: Option<String>,
|
pub display_name: Option<String>,
|
||||||
pub db_conn: Option<DatabaseConnection>,
|
pub db_conn: Option<DatabaseConnection>,
|
||||||
pub subscribe_txs: bool,
|
|
||||||
|
/// Track in-flight requests
|
||||||
|
pub(super) active_requests: AtomicUsize,
|
||||||
|
/// mapping of block numbers and hashes
|
||||||
|
pub(super) block_map: Option<BlocksByHashCache>,
|
||||||
|
/// created_at is only inside an Option so that the "Default" derive works. it will always be set.
|
||||||
|
pub(super) created_at: Option<Instant>,
|
||||||
/// most all requests prefer use the http_provider
|
/// most all requests prefer use the http_provider
|
||||||
pub(super) http_client: Option<reqwest::Client>,
|
pub(super) http_client: Option<reqwest::Client>,
|
||||||
pub(super) http_url: Option<Url>,
|
pub(super) http_url: Option<Url>,
|
||||||
@ -66,6 +72,8 @@ pub struct Web3Rpc {
|
|||||||
pub(super) automatic_block_limit: bool,
|
pub(super) automatic_block_limit: bool,
|
||||||
/// only use this rpc if everything else is lagging too far. this allows us to ignore fast but very low limit rpcs
|
/// only use this rpc if everything else is lagging too far. this allows us to ignore fast but very low limit rpcs
|
||||||
pub backup: bool,
|
pub backup: bool,
|
||||||
|
/// if subscribed to new heads, blocks are sent through this channel to update a parent Web3Rpcs
|
||||||
|
pub(super) block_and_rpc_sender: Option<mpsc::UnboundedSender<BlockAndRpc>>,
|
||||||
/// TODO: have an enum for this so that "no limit" prints pretty?
|
/// TODO: have an enum for this so that "no limit" prints pretty?
|
||||||
pub(super) block_data_limit: AtomicU64,
|
pub(super) block_data_limit: AtomicU64,
|
||||||
/// head_block is only inside an Option so that the "Default" derive works. it will always be set.
|
/// head_block is only inside an Option so that the "Default" derive works. it will always be set.
|
||||||
@ -73,10 +81,12 @@ pub struct Web3Rpc {
|
|||||||
/// Track head block latency.
|
/// Track head block latency.
|
||||||
/// TODO: This is in a sync lock, but writes are infrequent and quick. Is this actually okay? Set from a spawned task and read an atomic instead?
|
/// TODO: This is in a sync lock, but writes are infrequent and quick. Is this actually okay? Set from a spawned task and read an atomic instead?
|
||||||
pub(super) head_delay: RwLock<EwmaLatency>,
|
pub(super) head_delay: RwLock<EwmaLatency>,
|
||||||
|
/// false if a health check has failed
|
||||||
|
pub(super) healthy: AtomicBool,
|
||||||
/// Track peak request latency
|
/// Track peak request latency
|
||||||
/// peak_latency is only inside an Option so that the "Default" derive works. it will always be set.
|
/// peak_latency is only inside an Option so that the "Default" derive works. it will always be set.
|
||||||
pub(super) peak_latency: Option<PeakEwmaLatency>,
|
pub(super) peak_latency: Option<PeakEwmaLatency>,
|
||||||
/// Automatically set priority
|
/// Automatically set priority based on request latency and active requests
|
||||||
pub(super) tier: AtomicU32,
|
pub(super) tier: AtomicU32,
|
||||||
/// Track total internal requests served
|
/// Track total internal requests served
|
||||||
pub(super) internal_requests: AtomicUsize,
|
pub(super) internal_requests: AtomicUsize,
|
||||||
@ -87,15 +97,11 @@ pub struct Web3Rpc {
|
|||||||
/// Track time used by external requests served
|
/// Track time used by external requests served
|
||||||
/// request_ms_histogram is only inside an Option so that the "Default" derive works. it will always be set.
|
/// request_ms_histogram is only inside an Option so that the "Default" derive works. it will always be set.
|
||||||
pub(super) median_latency: Option<RollingQuantileLatency>,
|
pub(super) median_latency: Option<RollingQuantileLatency>,
|
||||||
/// Track in-flight requests
|
|
||||||
pub(super) active_requests: AtomicUsize,
|
|
||||||
/// disconnect_watch is only inside an Option so that the "Default" derive works. it will always be set.
|
/// disconnect_watch is only inside an Option so that the "Default" derive works. it will always be set.
|
||||||
/// todo!(qthis gets cloned a TON. probably too much. something seems wrong)
|
/// todo!(qthis gets cloned a TON. probably too much. something seems wrong)
|
||||||
pub(super) disconnect_watch: Option<watch::Sender<bool>>,
|
pub(super) disconnect_watch: Option<watch::Sender<bool>>,
|
||||||
/// created_at is only inside an Option so that the "Default" derive works. it will always be set.
|
/// if subscribed to pending transactions, transactions are sent through this channel to update a parent Web3App
|
||||||
pub(super) created_at: Option<Instant>,
|
pub(super) pending_txid_firehose: Option<Arc<DedupedBroadcaster<TxHash>>>,
|
||||||
/// false if a health check has failed
|
|
||||||
pub(super) healthy: AtomicBool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Web3Rpc {
|
impl Web3Rpc {
|
||||||
@ -200,11 +206,20 @@ impl Web3Rpc {
|
|||||||
// TODO: start optimistically?
|
// TODO: start optimistically?
|
||||||
let healthy = false.into();
|
let healthy = false.into();
|
||||||
|
|
||||||
|
let pending_txid_firehose = if config.subscribe_txs {
|
||||||
|
// TODO: error if subscribe_txs but not pending_txid_firehose
|
||||||
|
pending_txid_firehose
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let new_rpc = Self {
|
let new_rpc = Self {
|
||||||
automatic_block_limit,
|
automatic_block_limit,
|
||||||
backup,
|
backup,
|
||||||
block_data_limit,
|
block_data_limit,
|
||||||
block_interval,
|
block_interval,
|
||||||
|
block_map: Some(block_map),
|
||||||
|
chain_id,
|
||||||
created_at: Some(created_at),
|
created_at: Some(created_at),
|
||||||
display_name: config.display_name,
|
display_name: config.display_name,
|
||||||
hard_limit,
|
hard_limit,
|
||||||
@ -217,7 +232,8 @@ impl Web3Rpc {
|
|||||||
peak_latency: Some(peak_latency),
|
peak_latency: Some(peak_latency),
|
||||||
median_latency: Some(median_request_latency),
|
median_latency: Some(median_request_latency),
|
||||||
soft_limit: config.soft_limit,
|
soft_limit: config.soft_limit,
|
||||||
subscribe_txs: config.subscribe_txs,
|
pending_txid_firehose,
|
||||||
|
block_and_rpc_sender,
|
||||||
ws_url,
|
ws_url,
|
||||||
disconnect_watch: Some(disconnect_watch),
|
disconnect_watch: Some(disconnect_watch),
|
||||||
healthy,
|
healthy,
|
||||||
@ -230,16 +246,7 @@ impl Web3Rpc {
|
|||||||
// subscribing starts the connection (with retries)
|
// subscribing starts the connection (with retries)
|
||||||
let handle = {
|
let handle = {
|
||||||
let new_connection = new_connection.clone();
|
let new_connection = new_connection.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move { new_connection.subscribe_with_reconnect().await })
|
||||||
new_connection
|
|
||||||
.subscribe_with_reconnect(
|
|
||||||
block_map,
|
|
||||||
block_and_rpc_sender,
|
|
||||||
pending_txid_firehose,
|
|
||||||
chain_id,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((new_connection, handle))
|
Ok((new_connection, handle))
|
||||||
@ -492,10 +499,11 @@ impl Web3Rpc {
|
|||||||
|
|
||||||
/// query the web3 provider to confirm it is on the expected chain with the expected data available
|
/// query the web3 provider to confirm it is on the expected chain with the expected data available
|
||||||
/// TODO: this currently checks only the http if both http and ws are set. it should check both and make sure they match
|
/// TODO: this currently checks only the http if both http and ws are set. it should check both and make sure they match
|
||||||
async fn check_provider(self: &Arc<Self>, chain_id: u64) -> Web3ProxyResult<()> {
|
async fn check_provider(self: &Arc<Self>) -> Web3ProxyResult<()> {
|
||||||
// TODO: different handlers for backup vs primary
|
// TODO: different handlers for backup vs primary
|
||||||
let error_handler = Some(Level::TRACE.into());
|
let error_handler = Some(Level::TRACE.into());
|
||||||
|
|
||||||
|
// TODO: make this configurable. voltaire bundler uses web3_bundlerVersion
|
||||||
match self
|
match self
|
||||||
.internal_request::<_, String>(
|
.internal_request::<_, String>(
|
||||||
"web3_clientVersion".into(),
|
"web3_clientVersion".into(),
|
||||||
@ -536,10 +544,10 @@ impl Web3Rpc {
|
|||||||
|
|
||||||
trace!("found_chain_id: {:#?}", found_chain_id);
|
trace!("found_chain_id: {:#?}", found_chain_id);
|
||||||
|
|
||||||
if chain_id != found_chain_id.as_u64() {
|
if self.chain_id != found_chain_id.as_u64() {
|
||||||
return Err(anyhow::anyhow!(
|
return Err(anyhow::anyhow!(
|
||||||
"incorrect chain id! Config has {}, but RPC has {}",
|
"incorrect chain id! Config has {}, but RPC has {}",
|
||||||
chain_id,
|
self.chain_id,
|
||||||
found_chain_id
|
found_chain_id
|
||||||
)
|
)
|
||||||
.context(format!("failed @ {}", self))
|
.context(format!("failed @ {}", self))
|
||||||
@ -559,8 +567,6 @@ impl Web3Rpc {
|
|||||||
pub(crate) async fn send_head_block_result(
|
pub(crate) async fn send_head_block_result(
|
||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
new_head_block: Web3ProxyResult<Option<ArcBlock>>,
|
new_head_block: Web3ProxyResult<Option<ArcBlock>>,
|
||||||
block_and_rpc_sender: &mpsc::UnboundedSender<BlockAndRpc>,
|
|
||||||
block_map: &BlocksByHashCache,
|
|
||||||
) -> Web3ProxyResult<()> {
|
) -> Web3ProxyResult<()> {
|
||||||
let head_block_sender = self.head_block_sender.as_ref().unwrap();
|
let head_block_sender = self.head_block_sender.as_ref().unwrap();
|
||||||
|
|
||||||
@ -590,13 +596,17 @@ impl Web3Rpc {
|
|||||||
let new_hash = *new_head_block.hash();
|
let new_hash = *new_head_block.hash();
|
||||||
|
|
||||||
// if we already have this block saved, set new_head_block to that arc. otherwise store this copy
|
// if we already have this block saved, set new_head_block to that arc. otherwise store this copy
|
||||||
let new_head_block = block_map
|
let new_head_block = self
|
||||||
.get_with_by_ref(&new_hash, async move { new_head_block })
|
.block_map
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.get_with(new_hash, async move { new_head_block })
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
// we are synced! yey!
|
// we are synced! yey!
|
||||||
head_block_sender.send_replace(Some(new_head_block.clone()));
|
head_block_sender.send_replace(Some(new_head_block.clone()));
|
||||||
|
|
||||||
|
// TODO: checking this every time seems excessive
|
||||||
if self.block_data_limit() == U64::zero() {
|
if self.block_data_limit() == U64::zero() {
|
||||||
if let Err(err) = self.check_block_data_limit().await {
|
if let Err(err) = self.check_block_data_limit().await {
|
||||||
warn!(
|
warn!(
|
||||||
@ -623,9 +633,11 @@ impl Web3Rpc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// tell web3rpcs about this rpc having this block
|
// tell web3rpcs about this rpc having this block
|
||||||
block_and_rpc_sender
|
if let Some(block_and_rpc_sender) = &self.block_and_rpc_sender {
|
||||||
.send((new_head_block, self.clone()))
|
block_and_rpc_sender
|
||||||
.context("block_and_rpc_sender failed sending")?;
|
.send((new_head_block, self.clone()))
|
||||||
|
.context("block_and_rpc_sender failed sending")?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -691,24 +703,9 @@ impl Web3Rpc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// TODO: this needs to be a subscribe_with_reconnect that does a retry with jitter and exponential backoff
|
/// TODO: this needs to be a subscribe_with_reconnect that does a retry with jitter and exponential backoff
|
||||||
async fn subscribe_with_reconnect(
|
async fn subscribe_with_reconnect(self: Arc<Self>) -> Web3ProxyResult<()> {
|
||||||
self: Arc<Self>,
|
|
||||||
block_map: BlocksByHashCache,
|
|
||||||
block_and_rpc_sender: Option<mpsc::UnboundedSender<BlockAndRpc>>,
|
|
||||||
pending_txid_firehose: Option<Arc<DedupedBroadcaster<TxHash>>>,
|
|
||||||
chain_id: u64,
|
|
||||||
) -> Web3ProxyResult<()> {
|
|
||||||
loop {
|
loop {
|
||||||
if let Err(err) = self
|
if let Err(err) = self.clone().subscribe().await {
|
||||||
.clone()
|
|
||||||
.subscribe(
|
|
||||||
block_map.clone(),
|
|
||||||
block_and_rpc_sender.clone(),
|
|
||||||
pending_txid_firehose.clone(),
|
|
||||||
chain_id,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
if self.should_disconnect() {
|
if self.should_disconnect() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -733,13 +730,7 @@ impl Web3Rpc {
|
|||||||
/// subscribe to blocks and transactions
|
/// subscribe to blocks and transactions
|
||||||
/// This should only exit when the program is exiting.
|
/// This should only exit when the program is exiting.
|
||||||
/// TODO: should more of these args be on self? chain_id for sure
|
/// TODO: should more of these args be on self? chain_id for sure
|
||||||
async fn subscribe(
|
async fn subscribe(self: Arc<Self>) -> Web3ProxyResult<()> {
|
||||||
self: Arc<Self>,
|
|
||||||
block_map: BlocksByHashCache,
|
|
||||||
block_and_rpc_sender: Option<mpsc::UnboundedSender<BlockAndRpc>>,
|
|
||||||
pending_txid_firehose: Option<Arc<DedupedBroadcaster<TxHash>>>,
|
|
||||||
chain_id: u64,
|
|
||||||
) -> Web3ProxyResult<()> {
|
|
||||||
let error_handler = if self.backup {
|
let error_handler = if self.backup {
|
||||||
Some(RequestErrorHandler::DebugLevel)
|
Some(RequestErrorHandler::DebugLevel)
|
||||||
} else {
|
} else {
|
||||||
@ -768,7 +759,7 @@ impl Web3Rpc {
|
|||||||
trace!("starting subscriptions on {}", self);
|
trace!("starting subscriptions on {}", self);
|
||||||
|
|
||||||
if let Err(err) = self
|
if let Err(err) = self
|
||||||
.check_provider(chain_id)
|
.check_provider()
|
||||||
.await
|
.await
|
||||||
.web3_context("failed check_provider")
|
.web3_context("failed check_provider")
|
||||||
{
|
{
|
||||||
@ -780,7 +771,7 @@ impl Web3Rpc {
|
|||||||
let mut abort_handles = vec![];
|
let mut abort_handles = vec![];
|
||||||
|
|
||||||
// health check that runs if there haven't been any recent requests
|
// health check that runs if there haven't been any recent requests
|
||||||
let health_handle = if block_and_rpc_sender.is_some() {
|
let health_handle = if self.block_and_rpc_sender.is_some() {
|
||||||
// TODO: move this into a proper function
|
// TODO: move this into a proper function
|
||||||
let rpc = self.clone();
|
let rpc = self.clone();
|
||||||
|
|
||||||
@ -857,7 +848,7 @@ impl Web3Rpc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: if this fails too many times, reset the connection
|
// TODO: if this fails too many times, reset the connection
|
||||||
if let Err(err) = rpc.check_provider(chain_id).await {
|
if let Err(err) = rpc.check_provider().await {
|
||||||
rpc.healthy.store(false, atomic::Ordering::Relaxed);
|
rpc.healthy.store(false, atomic::Ordering::Relaxed);
|
||||||
|
|
||||||
// TODO: if rate limit error, set "retry_at"
|
// TODO: if rate limit error, set "retry_at"
|
||||||
@ -883,15 +874,10 @@ impl Web3Rpc {
|
|||||||
futures.push(health_handle);
|
futures.push(health_handle);
|
||||||
|
|
||||||
// subscribe to new heads
|
// subscribe to new heads
|
||||||
if let Some(block_and_rpc_sender) = block_and_rpc_sender.clone() {
|
if self.block_and_rpc_sender.is_some() {
|
||||||
let clone = self.clone();
|
let clone = self.clone();
|
||||||
let block_map = block_map.clone();
|
|
||||||
|
|
||||||
let f = async move {
|
let f = async move { clone.subscribe_new_heads().await };
|
||||||
clone
|
|
||||||
.subscribe_new_heads(block_and_rpc_sender, block_map)
|
|
||||||
.await
|
|
||||||
};
|
|
||||||
|
|
||||||
let h = tokio::spawn(f);
|
let h = tokio::spawn(f);
|
||||||
let a = h.abort_handle();
|
let a = h.abort_handle();
|
||||||
@ -901,23 +887,17 @@ impl Web3Rpc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// subscribe to new transactions
|
// subscribe to new transactions
|
||||||
if self.subscribe_txs && self.ws_provider.load().is_some() {
|
if self.pending_txid_firehose.is_some() && self.ws_provider.load().is_some() {
|
||||||
if let Some(pending_txid_firehose) = pending_txid_firehose.clone() {
|
let clone = self.clone();
|
||||||
let clone = self.clone();
|
|
||||||
|
|
||||||
let f = async move {
|
let f = async move { clone.subscribe_new_transactions().await };
|
||||||
clone
|
|
||||||
.subscribe_new_transactions(pending_txid_firehose)
|
|
||||||
.await
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: this is waking itself alot
|
// TODO: this is waking itself alot
|
||||||
let h = tokio::spawn(f);
|
let h = tokio::spawn(f);
|
||||||
let a = h.abort_handle();
|
let a = h.abort_handle();
|
||||||
|
|
||||||
futures.push(h);
|
futures.push(h);
|
||||||
abort_handles.push(a);
|
abort_handles.push(a);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// exit if any of the futures exit
|
// exit if any of the futures exit
|
||||||
@ -929,10 +909,7 @@ impl Web3Rpc {
|
|||||||
debug!(?first_exit, "subscriptions on {} exited", self);
|
debug!(?first_exit, "subscriptions on {} exited", self);
|
||||||
|
|
||||||
// clear the head block
|
// clear the head block
|
||||||
if let Some(block_and_rpc_sender) = block_and_rpc_sender {
|
self.send_head_block_result(Ok(None)).await?;
|
||||||
self.send_head_block_result(Ok(None), &block_and_rpc_sender, &block_map)
|
|
||||||
.await?
|
|
||||||
};
|
|
||||||
|
|
||||||
// stop the other futures
|
// stop the other futures
|
||||||
for a in abort_handles {
|
for a in abort_handles {
|
||||||
@ -945,12 +922,11 @@ impl Web3Rpc {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn subscribe_new_transactions(
|
async fn subscribe_new_transactions(self: &Arc<Self>) -> Web3ProxyResult<()> {
|
||||||
self: &Arc<Self>,
|
|
||||||
pending_txid_firehose: Arc<DedupedBroadcaster<TxHash>>,
|
|
||||||
) -> Web3ProxyResult<()> {
|
|
||||||
trace!("subscribing to new transactions on {}", self);
|
trace!("subscribing to new transactions on {}", self);
|
||||||
|
|
||||||
|
let pending_txid_firehose = self.pending_txid_firehose.as_ref().unwrap();
|
||||||
|
|
||||||
if let Some(ws_provider) = self.ws_provider.load().as_ref() {
|
if let Some(ws_provider) = self.ws_provider.load().as_ref() {
|
||||||
// todo: move subscribe_blocks onto the request handle instead of having a seperate wait_for_throttle
|
// todo: move subscribe_blocks onto the request handle instead of having a seperate wait_for_throttle
|
||||||
self.wait_for_throttle(Instant::now() + Duration::from_secs(5))
|
self.wait_for_throttle(Instant::now() + Duration::from_secs(5))
|
||||||
@ -973,11 +949,7 @@ impl Web3Rpc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Subscribe to new block headers.
|
/// Subscribe to new block headers.
|
||||||
async fn subscribe_new_heads(
|
async fn subscribe_new_heads(self: &Arc<Self>) -> Web3ProxyResult<()> {
|
||||||
self: &Arc<Self>,
|
|
||||||
block_sender: mpsc::UnboundedSender<BlockAndRpc>,
|
|
||||||
block_map: BlocksByHashCache,
|
|
||||||
) -> Web3ProxyResult<()> {
|
|
||||||
trace!("subscribing to new heads on {}", self);
|
trace!("subscribing to new heads on {}", self);
|
||||||
|
|
||||||
let error_handler = if self.backup {
|
let error_handler = if self.backup {
|
||||||
@ -1004,14 +976,12 @@ impl Web3Rpc {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
self.send_head_block_result(latest_block, &block_sender, &block_map)
|
self.send_head_block_result(latest_block).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
while let Some(block) = blocks.next().await {
|
while let Some(block) = blocks.next().await {
|
||||||
let block = Ok(Some(Arc::new(block)));
|
let block = Ok(Some(Arc::new(block)));
|
||||||
|
|
||||||
self.send_head_block_result(block, &block_sender, &block_map)
|
self.send_head_block_result(block).await?;
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
} else if self.http_client.is_some() {
|
} else if self.http_client.is_some() {
|
||||||
// there is a "watch_blocks" function, but a lot of public nodes (including llamanodes) do not support the necessary rpc endpoints
|
// there is a "watch_blocks" function, but a lot of public nodes (including llamanodes) do not support the necessary rpc endpoints
|
||||||
@ -1029,8 +999,7 @@ impl Web3Rpc {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
self.send_head_block_result(block_result, &block_sender, &block_map)
|
self.send_head_block_result(block_result).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
// TODO: should this select be at the start or end of the loop?
|
// TODO: should this select be at the start or end of the loop?
|
||||||
i.tick().await;
|
i.tick().await;
|
||||||
@ -1040,8 +1009,7 @@ impl Web3Rpc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clear the head block. this might not be needed, but it won't hurt
|
// clear the head block. this might not be needed, but it won't hurt
|
||||||
self.send_head_block_result(Ok(None), &block_sender, &block_map)
|
self.send_head_block_result(Ok(None)).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
if self.should_disconnect() {
|
if self.should_disconnect() {
|
||||||
trace!(%self, "new heads subscription exited");
|
trace!(%self, "new heads subscription exited");
|
||||||
|
Loading…
Reference in New Issue
Block a user