mirror of
https://github.com/serai-dex/serai.git
synced 2025-04-22 22:18:15 +00:00
Take advantage of RangeInclusive for specifying filters' blocks
This commit is contained in:
parent
604a4b2442
commit
29bb5e21ab
4 changed files with 32 additions and 37 deletions
|
@ -2,6 +2,7 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
use core::ops::RangeInclusive;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use alloy_core::primitives::{Address, U256};
|
||||
|
@ -76,8 +77,8 @@ pub struct TopLevelTransfers {
|
|||
pub struct Erc20;
|
||||
impl Erc20 {
|
||||
/// The filter for transfer logs of the specified ERC20, to the specified recipient.
|
||||
fn transfer_filter(from_block: u64, to_block: u64, erc20: Address, to: Address) -> Filter {
|
||||
let filter = Filter::new().from_block(from_block).to_block(to_block);
|
||||
fn transfer_filter(blocks: RangeInclusive<u64>, erc20: Address, to: Address) -> Filter {
|
||||
let filter = Filter::new().select(blocks);
|
||||
filter.address(erc20).event_signature(Transfer::SIGNATURE_HASH).topic2(to.into_word())
|
||||
}
|
||||
|
||||
|
@ -180,14 +181,13 @@ impl Erc20 {
|
|||
/// The `transfers` in the result are unordered. The `logs` are sorted by index.
|
||||
pub async fn top_level_transfers_unordered(
|
||||
provider: &RootProvider<SimpleRequest>,
|
||||
from_block: u64,
|
||||
to_block: u64,
|
||||
blocks: RangeInclusive<u64>,
|
||||
erc20: Address,
|
||||
to: Address,
|
||||
) -> Result<TopLevelTransfers, RpcError<TransportErrorKind>> {
|
||||
let mut logs = {
|
||||
// Get all transfers within these blocks
|
||||
let logs = provider.get_logs(&Self::transfer_filter(from_block, to_block, erc20, to)).await?;
|
||||
let logs = provider.get_logs(&Self::transfer_filter(blocks, erc20, to)).await?;
|
||||
|
||||
// The logs, indexed by their transactions
|
||||
let mut transaction_logs = HashMap::new();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
use core::ops::RangeInclusive;
|
||||
use std::{
|
||||
sync::Arc,
|
||||
collections::{HashSet, HashMap},
|
||||
|
@ -459,13 +460,13 @@ impl Router {
|
|||
/// This is not guaranteed to return them in any order.
|
||||
pub async fn in_instructions_unordered(
|
||||
&self,
|
||||
from_block: u64,
|
||||
to_block: u64,
|
||||
blocks: RangeInclusive<u64>,
|
||||
allowed_erc20s: &HashSet<Address>,
|
||||
) -> Result<Vec<InInstruction>, RpcError<TransportErrorKind>> {
|
||||
// The InInstruction events for this block
|
||||
let in_instruction_logs = {
|
||||
let filter = Filter::new().from_block(from_block).to_block(to_block).address(self.address);
|
||||
// https://github.com/rust-lang/rust/issues/27186
|
||||
let filter = Filter::new().select(blocks.clone()).address(self.address);
|
||||
let filter = filter.event_signature(InInstructionEvent::SIGNATURE_HASH);
|
||||
self.provider.get_logs(&filter).await?
|
||||
};
|
||||
|
@ -478,18 +479,15 @@ impl Router {
|
|||
let erc20_transfer_logs = {
|
||||
let mut transfers = FuturesUnordered::new();
|
||||
for erc20 in allowed_erc20s {
|
||||
transfers.push(async move {
|
||||
(
|
||||
erc20,
|
||||
Erc20::top_level_transfers_unordered(
|
||||
&self.provider,
|
||||
from_block,
|
||||
to_block,
|
||||
*erc20,
|
||||
self.address,
|
||||
)
|
||||
.await,
|
||||
)
|
||||
transfers.push({
|
||||
// https://github.com/rust-lang/rust/issues/27186
|
||||
let blocks: RangeInclusive<u64> = blocks.clone();
|
||||
async move {
|
||||
let transfers =
|
||||
Erc20::top_level_transfers_unordered(&self.provider, blocks, *erc20, self.address)
|
||||
.await;
|
||||
(erc20, transfers)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -626,8 +624,7 @@ impl Router {
|
|||
/// Fetch the executed actions for the specified range of blocks.
|
||||
pub async fn executed(
|
||||
&self,
|
||||
from_block: u64,
|
||||
to_block: u64,
|
||||
blocks: RangeInclusive<u64>,
|
||||
) -> Result<Vec<Executed>, RpcError<TransportErrorKind>> {
|
||||
fn decode<E: SolEvent>(log: &Log) -> Result<E, RpcError<TransportErrorKind>> {
|
||||
Ok(
|
||||
|
@ -643,7 +640,7 @@ impl Router {
|
|||
)
|
||||
}
|
||||
|
||||
let filter = Filter::new().from_block(from_block).to_block(to_block).address(self.address);
|
||||
let filter = Filter::new().select(blocks).address(self.address);
|
||||
let mut logs = self.provider.get_logs(&filter).await?;
|
||||
logs.sort_by_key(|log| (log.block_number, log.log_index));
|
||||
|
||||
|
@ -707,10 +704,9 @@ impl Router {
|
|||
/// Fetch the `Escape`s from the smart contract through the escape hatch.
|
||||
pub async fn escapes(
|
||||
&self,
|
||||
from_block: u64,
|
||||
to_block: u64,
|
||||
blocks: RangeInclusive<u64>,
|
||||
) -> Result<Vec<Escape>, RpcError<TransportErrorKind>> {
|
||||
let filter = Filter::new().from_block(from_block).to_block(to_block).address(self.address);
|
||||
let filter = Filter::new().select(blocks).address(self.address);
|
||||
let mut logs =
|
||||
self.provider.get_logs(&filter.event_signature(EscapedEvent::SIGNATURE_HASH)).await?;
|
||||
logs.sort_by_key(|log| (log.block_number, log.log_index));
|
||||
|
|
|
@ -144,7 +144,7 @@ impl Test {
|
|||
// Confirm nonce 0 was used as such
|
||||
{
|
||||
let block = receipt.block_number.unwrap();
|
||||
let executed = router.executed(block, block).await.unwrap();
|
||||
let executed = router.executed(block ..= block).await.unwrap();
|
||||
assert_eq!(executed.len(), 1);
|
||||
assert_eq!(executed[0], Executed::NextSeraiKeySet { nonce: 0, key: public_key.eth_repr() });
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ impl Test {
|
|||
|
||||
{
|
||||
let block = receipt.block_number.unwrap();
|
||||
let executed = self.router.executed(block, block).await.unwrap();
|
||||
let executed = self.router.executed(block ..= block).await.unwrap();
|
||||
assert_eq!(executed.len(), 1);
|
||||
assert_eq!(
|
||||
executed[0],
|
||||
|
@ -236,7 +236,7 @@ impl Test {
|
|||
|
||||
{
|
||||
let block = receipt.block_number.unwrap();
|
||||
let executed = self.router.executed(block, block).await.unwrap();
|
||||
let executed = self.router.executed(block ..= block).await.unwrap();
|
||||
assert_eq!(executed.len(), 1);
|
||||
assert_eq!(
|
||||
executed[0],
|
||||
|
@ -283,15 +283,14 @@ impl Test {
|
|||
if matches!(coin, Coin::Erc20(_)) {
|
||||
// If we don't whitelist this token, we shouldn't be yielded an InInstruction
|
||||
let in_instructions =
|
||||
self.router.in_instructions_unordered(block, block, &HashSet::new()).await.unwrap();
|
||||
self.router.in_instructions_unordered(block ..= block, &HashSet::new()).await.unwrap();
|
||||
assert!(in_instructions.is_empty());
|
||||
}
|
||||
|
||||
let in_instructions = self
|
||||
.router
|
||||
.in_instructions_unordered(
|
||||
block,
|
||||
block,
|
||||
block ..= block,
|
||||
&if let Coin::Erc20(token) = coin { HashSet::from([token]) } else { HashSet::new() },
|
||||
)
|
||||
.await
|
||||
|
@ -359,7 +358,7 @@ impl Test {
|
|||
|
||||
{
|
||||
let block = receipt.block_number.unwrap();
|
||||
let executed = self.router.executed(block, block).await.unwrap();
|
||||
let executed = self.router.executed(block ..= block).await.unwrap();
|
||||
assert_eq!(executed.len(), 1);
|
||||
assert_eq!(executed[0], Executed::EscapeHatch { nonce: self.state.next_nonce, escape_to });
|
||||
}
|
||||
|
@ -707,7 +706,7 @@ async fn test_escape_hatch() {
|
|||
|
||||
let block = receipt.block_number.unwrap();
|
||||
assert_eq!(
|
||||
test.router.escapes(block, block).await.unwrap(),
|
||||
test.router.escapes(block ..= block).await.unwrap(),
|
||||
vec![Escape { coin: Coin::Ether, amount: U256::from(1) }],
|
||||
);
|
||||
|
||||
|
@ -730,7 +729,7 @@ async fn test_escape_hatch() {
|
|||
assert!(receipt.status());
|
||||
|
||||
let block = receipt.block_number.unwrap();
|
||||
assert_eq!(test.router.escapes(block, block).await.unwrap(), vec![Escape { coin, amount }],);
|
||||
assert_eq!(test.router.escapes(block ..= block).await.unwrap(), vec![Escape { coin, amount }],);
|
||||
assert_eq!(erc20.balance_of(&test, test.router.address()).await, U256::from(0));
|
||||
assert_eq!(erc20.balance_of(&test, test.state.escaped_to.unwrap()).await, amount);
|
||||
}
|
||||
|
|
|
@ -160,10 +160,10 @@ impl<D: Db> ScannerFeed for Rpc<D> {
|
|||
block: Header,
|
||||
) -> Result<(Vec<EthereumInInstruction>, Vec<Executed>), RpcError<TransportErrorKind>> {
|
||||
let instructions = router
|
||||
.in_instructions_unordered(block.number, block.number, &HashSet::from(TOKENS))
|
||||
.in_instructions_unordered(block.number ..= block.number, &HashSet::from(TOKENS))
|
||||
.await?;
|
||||
|
||||
let executed = router.executed(block.number, block.number).await?;
|
||||
let executed = router.executed(block.number ..= block.number).await?;
|
||||
|
||||
Ok((instructions, executed))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue