pub async fn resolve_filter_block_hash(&self, filter: &mut Filter) -> Result<(), Web3Error> {
        match (filter.block_hash, filter.from_block, filter.to_block) {
            (Some(block_hash), None, None) => {
                let mut storage = self.acquire_connection().await?;
                let block_number = self
                    .resolve_block(&mut storage, api::BlockId::Hash(block_hash))
                    .await?;
                filter.from_block = Some(api::BlockNumber::Number(block_number.0.into()));
                filter.to_block = Some(api::BlockNumber::Number(block_number.0.into()));
                Ok(())
            }
            (Some(_), _, _) => Err(Web3Error::InvalidFilterBlockHash),
            (None, _, _) => Ok(()),
        }
    }
If filter has `block_hash` then it resolves block number by hash and sets it to `from_block` and `to_block`.
core/node/api_server/src/web3/state.rs