Skip to content

Commit 1da3f7e

Browse files
authored
feat(eth-watch): do not query events from earliest block (#2810)
## What ❔ Removes querying from the earliest batch in eth watch. Instead queries for constant block range and splits queried range in parts if needed ## Why ❔ Vanilla reth doesn't allow eth_logs requests where block range is greater than 1_000_000. This changes allows eth watch to work with this limitation. ## Checklist <!-- Check your PR fulfills the following items. --> <!-- For draft PRs check the boxes as you complete them. --> - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zk fmt` and `zk lint`.
1 parent 958dfdc commit 1da3f7e

File tree

1 file changed

+78
-61
lines changed

1 file changed

+78
-61
lines changed

core/node/eth_watch/src/client.rs

Lines changed: 78 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -88,75 +88,34 @@ impl EthHttpQueryClient {
8888
}
8989
}
9090

91-
async fn get_filter_logs(
91+
fn get_default_address_list(&self) -> Vec<Address> {
92+
[
93+
Some(self.diamond_proxy_addr),
94+
Some(self.governance_address),
95+
self.state_transition_manager_address,
96+
self.chain_admin_address,
97+
]
98+
.into_iter()
99+
.flatten()
100+
.collect()
101+
}
102+
103+
async fn get_events_inner(
92104
&self,
93105
from: BlockNumber,
94106
to: BlockNumber,
95-
topics: Vec<H256>,
107+
topics1: Vec<H256>,
108+
topics2: Vec<H256>,
109+
addresses: Vec<Address>,
110+
retries_left: usize,
96111
) -> EnrichedClientResult<Vec<Log>> {
97112
let filter = FilterBuilder::default()
98-
.address(
99-
[
100-
Some(self.diamond_proxy_addr),
101-
Some(self.governance_address),
102-
self.state_transition_manager_address,
103-
self.chain_admin_address,
104-
]
105-
.into_iter()
106-
.flatten()
107-
.collect(),
108-
)
109113
.from_block(from)
110114
.to_block(to)
111-
.topics(Some(topics), None, None, None)
115+
.topics(Some(topics1), Some(topics2), None, None)
116+
.address(addresses)
112117
.build();
113-
self.client.logs(&filter).await
114-
}
115-
}
116-
117-
#[async_trait::async_trait]
118-
impl EthClient for EthHttpQueryClient {
119-
async fn scheduler_vk_hash(
120-
&self,
121-
verifier_address: Address,
122-
) -> Result<H256, ContractCallError> {
123-
// New verifier returns the hash of the verification key.
124-
CallFunctionArgs::new("verificationKeyHash", ())
125-
.for_contract(verifier_address, &self.verifier_contract_abi)
126-
.call(&self.client)
127-
.await
128-
}
129-
130-
async fn diamond_cut_by_version(
131-
&self,
132-
packed_version: H256,
133-
) -> EnrichedClientResult<Option<Vec<u8>>> {
134-
let Some(state_transition_manager_address) = self.state_transition_manager_address else {
135-
return Ok(None);
136-
};
137-
138-
let filter = FilterBuilder::default()
139-
.address(vec![state_transition_manager_address])
140-
.from_block(BlockNumber::Earliest)
141-
.to_block(BlockNumber::Latest)
142-
.topics(
143-
Some(vec![self.new_upgrade_cut_data_signature]),
144-
Some(vec![packed_version]),
145-
None,
146-
None,
147-
)
148-
.build();
149-
let logs = self.client.logs(&filter).await?;
150-
Ok(logs.into_iter().next().map(|log| log.data.0))
151-
}
152-
153-
async fn get_events(
154-
&self,
155-
from: BlockNumber,
156-
to: BlockNumber,
157-
retries_left: usize,
158-
) -> EnrichedClientResult<Vec<Log>> {
159-
let mut result = self.get_filter_logs(from, to, self.topics.clone()).await;
118+
let mut result = self.client.logs(&filter).await;
160119

161120
// This code is compatible with both Infura and Alchemy API providers.
162121
// Note: we don't handle rate-limits here - assumption is that we're never going to hit them.
@@ -225,6 +184,64 @@ impl EthClient for EthHttpQueryClient {
225184

226185
result
227186
}
187+
}
188+
189+
#[async_trait::async_trait]
190+
impl EthClient for EthHttpQueryClient {
191+
async fn scheduler_vk_hash(
192+
&self,
193+
verifier_address: Address,
194+
) -> Result<H256, ContractCallError> {
195+
// New verifier returns the hash of the verification key.
196+
CallFunctionArgs::new("verificationKeyHash", ())
197+
.for_contract(verifier_address, &self.verifier_contract_abi)
198+
.call(&self.client)
199+
.await
200+
}
201+
202+
async fn diamond_cut_by_version(
203+
&self,
204+
packed_version: H256,
205+
) -> EnrichedClientResult<Option<Vec<u8>>> {
206+
const LOOK_BACK_BLOCK_RANGE: u64 = 1_000_000;
207+
208+
let Some(state_transition_manager_address) = self.state_transition_manager_address else {
209+
return Ok(None);
210+
};
211+
212+
let to_block = self.client.block_number().await?;
213+
let from_block = to_block.saturating_sub((LOOK_BACK_BLOCK_RANGE - 1).into());
214+
215+
let logs = self
216+
.get_events_inner(
217+
from_block.into(),
218+
to_block.into(),
219+
vec![self.new_upgrade_cut_data_signature],
220+
vec![packed_version],
221+
vec![state_transition_manager_address],
222+
RETRY_LIMIT,
223+
)
224+
.await?;
225+
226+
Ok(logs.into_iter().next().map(|log| log.data.0))
227+
}
228+
229+
async fn get_events(
230+
&self,
231+
from: BlockNumber,
232+
to: BlockNumber,
233+
retries_left: usize,
234+
) -> EnrichedClientResult<Vec<Log>> {
235+
self.get_events_inner(
236+
from,
237+
to,
238+
self.topics.clone(),
239+
Vec::new(),
240+
self.get_default_address_list(),
241+
retries_left,
242+
)
243+
.await
244+
}
228245

229246
async fn finalized_block_number(&self) -> EnrichedClientResult<u64> {
230247
if let Some(confirmations) = self.confirmations_for_eth_event {

0 commit comments

Comments
 (0)