1use crate::{
2 abi::ethereum_types::BloomInput,
3 types::{Address, BlockNumber, Bloom, Log, H160, H256, U256, U64},
4 utils::keccak256,
5};
6use serde::{
7 de::{DeserializeOwned, MapAccess, Visitor},
8 ser::SerializeStruct,
9 Deserialize, Deserializer, Serialize, Serializer,
10};
11use std::ops::{Range, RangeFrom, RangeTo};
12
13pub type BloomFilter = Vec<Option<Bloom>>;
14
15pub type Topic = ValueOrArray<Option<H256>>;
17
18#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
20pub enum FilterBlockOption {
21 Range { from_block: Option<BlockNumber>, to_block: Option<BlockNumber> },
22 AtBlockHash(H256),
23}
24
25impl FilterBlockOption {
26 pub fn get_to_block(&self) -> Option<&BlockNumber> {
27 match self {
28 FilterBlockOption::Range { to_block, .. } => to_block.as_ref(),
29 FilterBlockOption::AtBlockHash(_) => None,
30 }
31 }
32
33 pub fn get_from_block(&self) -> Option<&BlockNumber> {
34 match self {
35 FilterBlockOption::Range { from_block, .. } => from_block.as_ref(),
36 FilterBlockOption::AtBlockHash(_) => None,
37 }
38 }
39}
40
41impl From<BlockNumber> for FilterBlockOption {
42 fn from(block: BlockNumber) -> Self {
43 let block = Some(block);
44 FilterBlockOption::Range { from_block: block, to_block: block }
45 }
46}
47
48impl From<U64> for FilterBlockOption {
49 fn from(block: U64) -> Self {
50 BlockNumber::from(block).into()
51 }
52}
53
54impl From<u64> for FilterBlockOption {
55 fn from(block: u64) -> Self {
56 BlockNumber::from(block).into()
57 }
58}
59
60impl<T: Into<BlockNumber>> From<Range<T>> for FilterBlockOption {
61 fn from(r: Range<T>) -> Self {
62 let from_block = Some(r.start.into());
63 let to_block = Some(r.end.into());
64 FilterBlockOption::Range { from_block, to_block }
65 }
66}
67
68impl<T: Into<BlockNumber>> From<RangeTo<T>> for FilterBlockOption {
69 fn from(r: RangeTo<T>) -> Self {
70 let to_block = Some(r.end.into());
71 FilterBlockOption::Range { from_block: Some(BlockNumber::Earliest), to_block }
72 }
73}
74
75impl<T: Into<BlockNumber>> From<RangeFrom<T>> for FilterBlockOption {
76 fn from(r: RangeFrom<T>) -> Self {
77 let from_block = Some(r.start.into());
78 FilterBlockOption::Range { from_block, to_block: Some(BlockNumber::Latest) }
79 }
80}
81
82impl From<H256> for FilterBlockOption {
83 fn from(hash: H256) -> Self {
84 FilterBlockOption::AtBlockHash(hash)
85 }
86}
87
88impl Default for FilterBlockOption {
89 fn default() -> Self {
90 FilterBlockOption::Range { from_block: None, to_block: None }
91 }
92}
93
94impl FilterBlockOption {
95 #[must_use]
96 pub fn set_from_block(&self, block: BlockNumber) -> Self {
97 let to_block =
98 if let FilterBlockOption::Range { to_block, .. } = self { *to_block } else { None };
99
100 FilterBlockOption::Range { from_block: Some(block), to_block }
101 }
102
103 #[must_use]
104 pub fn set_to_block(&self, block: BlockNumber) -> Self {
105 let from_block =
106 if let FilterBlockOption::Range { from_block, .. } = self { *from_block } else { None };
107
108 FilterBlockOption::Range { from_block, to_block: Some(block) }
109 }
110
111 #[must_use]
112 pub fn set_hash(&self, hash: H256) -> Self {
113 FilterBlockOption::AtBlockHash(hash)
114 }
115}
116
117#[derive(Default, Debug, PartialEq, Eq, Clone, Hash)]
119pub struct Filter {
120 pub block_option: FilterBlockOption,
124
125 pub address: Option<ValueOrArray<Address>>,
127
128 pub topics: [Option<Topic>; 4],
132}
133
134impl Filter {
135 pub fn new() -> Self {
136 Self::default()
137 }
138
139 #[must_use]
201 pub fn select(mut self, filter: impl Into<FilterBlockOption>) -> Self {
202 self.block_option = filter.into();
203 self
204 }
205
206 #[allow(clippy::wrong_self_convention)]
207 #[must_use]
208 pub fn from_block<T: Into<BlockNumber>>(mut self, block: T) -> Self {
209 self.block_option = self.block_option.set_from_block(block.into());
210 self
211 }
212
213 #[allow(clippy::wrong_self_convention)]
214 #[must_use]
215 pub fn to_block<T: Into<BlockNumber>>(mut self, block: T) -> Self {
216 self.block_option = self.block_option.set_to_block(block.into());
217 self
218 }
219
220 #[allow(clippy::wrong_self_convention)]
221 #[must_use]
222 pub fn at_block_hash<T: Into<H256>>(mut self, hash: T) -> Self {
223 self.block_option = self.block_option.set_hash(hash.into());
224 self
225 }
226 #[must_use]
252 pub fn address<T: Into<ValueOrArray<Address>>>(mut self, address: T) -> Self {
253 self.address = Some(address.into());
254 self
255 }
256
257 #[must_use]
259 pub fn event(self, event_name: &str) -> Self {
260 let hash = H256::from(keccak256(event_name.as_bytes()));
261 self.topic0(hash)
262 }
263
264 #[must_use]
266 pub fn events(self, events: impl IntoIterator<Item = impl AsRef<[u8]>>) -> Self {
267 let events =
268 events.into_iter().map(|e| H256::from(keccak256(e.as_ref()))).collect::<Vec<_>>();
269 self.topic0(events)
270 }
271
272 #[must_use]
274 pub fn topic0<T: Into<Topic>>(mut self, topic: T) -> Self {
275 self.topics[0] = Some(topic.into());
276 self
277 }
278
279 #[must_use]
281 pub fn topic1<T: Into<Topic>>(mut self, topic: T) -> Self {
282 self.topics[1] = Some(topic.into());
283 self
284 }
285
286 #[must_use]
288 pub fn topic2<T: Into<Topic>>(mut self, topic: T) -> Self {
289 self.topics[2] = Some(topic.into());
290 self
291 }
292
293 #[must_use]
295 pub fn topic3<T: Into<Topic>>(mut self, topic: T) -> Self {
296 self.topics[3] = Some(topic.into());
297 self
298 }
299
300 pub fn is_paginatable(&self) -> bool {
301 self.get_from_block().is_some()
302 }
303
304 pub fn get_to_block(&self) -> Option<U64> {
306 self.block_option.get_to_block().and_then(|b| b.as_number())
307 }
308
309 pub fn get_from_block(&self) -> Option<U64> {
311 self.block_option.get_from_block().and_then(|b| b.as_number())
312 }
313
314 pub fn get_block_hash(&self) -> Option<H256> {
316 match self.block_option {
317 FilterBlockOption::AtBlockHash(hash) => Some(hash),
318 FilterBlockOption::Range { .. } => None,
319 }
320 }
321
322 fn flatten(&self) -> Vec<ValueOrArray<Option<H256>>> {
324 fn cartesian(lists: &[Vec<Option<H256>>]) -> Vec<Vec<Option<H256>>> {
325 let mut res = Vec::new();
326 let mut list_iter = lists.iter();
327 if let Some(first_list) = list_iter.next() {
328 for &i in first_list {
329 res.push(vec![i]);
330 }
331 }
332 for l in list_iter {
333 let mut tmp = Vec::new();
334 for r in res {
335 for &el in l {
336 let mut tmp_el = r.clone();
337 tmp_el.push(el);
338 tmp.push(tmp_el);
339 }
340 }
341 res = tmp;
342 }
343 res
344 }
345 let mut out = Vec::new();
346 let mut tmp = Vec::new();
347 for v in self.topics.iter() {
348 let v = if let Some(v) = v {
349 match v {
350 ValueOrArray::Value(s) => {
351 vec![*s]
352 }
353 ValueOrArray::Array(s) => s.clone(),
354 }
355 } else {
356 vec![None]
357 };
358 tmp.push(v);
359 }
360 for v in cartesian(&tmp) {
361 out.push(ValueOrArray::Array(v));
362 }
363 out
364 }
365
366 pub fn topics(&self) -> impl Iterator<Item = &Topic> + '_ {
368 self.topics.iter().flatten()
369 }
370
371 pub fn has_topics(&self) -> bool {
373 self.topics.iter().any(|t| t.is_some())
374 }
375}
376
377impl Serialize for Filter {
378 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
379 where
380 S: Serializer,
381 {
382 let mut s = serializer.serialize_struct("Filter", 5)?;
383 match self.block_option {
384 FilterBlockOption::Range { from_block, to_block } => {
385 if let Some(ref from_block) = from_block {
386 s.serialize_field("fromBlock", from_block)?;
387 }
388
389 if let Some(ref to_block) = to_block {
390 s.serialize_field("toBlock", to_block)?;
391 }
392 }
393
394 FilterBlockOption::AtBlockHash(ref h) => s.serialize_field("blockHash", h)?,
395 }
396
397 if let Some(ref address) = self.address {
398 s.serialize_field("address", address)?;
399 }
400
401 let mut filtered_topics = Vec::new();
402 for i in 0..4 {
403 if self.topics[i].is_some() {
404 filtered_topics.push(&self.topics[i]);
405 } else {
406 if self.topics[i + 1..].iter().any(|x| x.is_some()) {
408 filtered_topics.push(&None);
409 }
410 }
411 }
412 s.serialize_field("topics", &filtered_topics)?;
413
414 s.end()
415 }
416}
417
418impl<'de> Deserialize<'de> for Filter {
419 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
420 where
421 D: Deserializer<'de>,
422 {
423 struct FilterVisitor;
424
425 impl<'de> Visitor<'de> for FilterVisitor {
426 type Value = Filter;
427
428 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
429 formatter.write_str("Filter object")
430 }
431
432 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
433 where
434 A: MapAccess<'de>,
435 {
436 let mut from_block: Option<Option<BlockNumber>> = None;
437 let mut to_block: Option<Option<BlockNumber>> = None;
438 let mut block_hash: Option<Option<H256>> = None;
439 let mut address: Option<Option<ValueOrArray<Address>>> = None;
440 let mut topics: Option<Option<Vec<Option<Topic>>>> = None;
441
442 while let Some(key) = map.next_key::<String>()? {
443 match key.as_str() {
444 "fromBlock" => {
445 if from_block.is_some() {
446 return Err(serde::de::Error::duplicate_field("fromBlock"))
447 }
448 if block_hash.is_some() {
449 return Err(serde::de::Error::custom(
450 "fromBlock not allowed with blockHash",
451 ))
452 }
453 from_block = Some(map.next_value()?)
454 }
455 "toBlock" => {
456 if to_block.is_some() {
457 return Err(serde::de::Error::duplicate_field("toBlock"))
458 }
459 if block_hash.is_some() {
460 return Err(serde::de::Error::custom(
461 "toBlock not allowed with blockHash",
462 ))
463 }
464 to_block = Some(map.next_value()?)
465 }
466 "blockHash" => {
467 if block_hash.is_some() {
468 return Err(serde::de::Error::duplicate_field("blockHash"))
469 }
470 if from_block.is_some() || to_block.is_some() {
471 return Err(serde::de::Error::custom(
472 "fromBlock,toBlock not allowed with blockHash",
473 ))
474 }
475 block_hash = Some(map.next_value()?)
476 }
477 "address" => {
478 if address.is_some() {
479 return Err(serde::de::Error::duplicate_field("address"))
480 }
481 address = Some(map.next_value()?)
482 }
483 "topics" => {
484 if topics.is_some() {
485 return Err(serde::de::Error::duplicate_field("topics"))
486 }
487 topics = Some(map.next_value()?)
488 }
489
490 key => {
491 return Err(serde::de::Error::unknown_field(
492 key,
493 &["fromBlock", "toBlock", "address", "topics", "blockHash"],
494 ))
495 }
496 }
497 }
498
499 let from_block = from_block.unwrap_or_default();
500 let to_block = to_block.unwrap_or_default();
501 let block_hash = block_hash.unwrap_or_default();
502 let address = address.unwrap_or_default();
503 let topics_vec = topics.flatten().unwrap_or_default();
504
505 if topics_vec.len() > 4 {
507 return Err(serde::de::Error::custom("exceeded maximum topics len"))
508 }
509 let mut topics: [Option<Topic>; 4] = [None, None, None, None];
510 for (idx, topic) in topics_vec.into_iter().enumerate() {
511 topics[idx] = topic;
512 }
513
514 let block_option = if let Some(block_hash) = block_hash {
515 FilterBlockOption::AtBlockHash(block_hash)
516 } else {
517 FilterBlockOption::Range { from_block, to_block }
518 };
519
520 Ok(Filter { block_option, address, topics })
521 }
522 }
523
524 deserializer.deserialize_any(FilterVisitor)
525 }
526}
527
528#[derive(Debug, PartialEq, Eq, Clone, Hash)]
530pub enum ValueOrArray<T> {
531 Value(T),
533 Array(Vec<T>),
535}
536
537impl From<H160> for ValueOrArray<H160> {
538 fn from(src: H160) -> Self {
539 ValueOrArray::Value(src)
540 }
541}
542
543impl From<Vec<H160>> for ValueOrArray<H160> {
544 fn from(src: Vec<H160>) -> Self {
545 ValueOrArray::Array(src)
546 }
547}
548
549impl From<H256> for Topic {
550 fn from(src: H256) -> Self {
551 ValueOrArray::Value(Some(src))
552 }
553}
554
555impl From<Vec<H256>> for ValueOrArray<H256> {
556 fn from(src: Vec<H256>) -> Self {
557 ValueOrArray::Array(src)
558 }
559}
560
561impl From<ValueOrArray<H256>> for Topic {
562 fn from(src: ValueOrArray<H256>) -> Self {
563 match src {
564 ValueOrArray::Value(val) => ValueOrArray::Value(Some(val)),
565 ValueOrArray::Array(arr) => arr.into(),
566 }
567 }
568}
569
570impl<I: Into<H256>> From<Vec<I>> for Topic {
571 fn from(src: Vec<I>) -> Self {
572 ValueOrArray::Array(src.into_iter().map(Into::into).map(Some).collect())
573 }
574}
575
576impl From<Address> for Topic {
577 fn from(src: Address) -> Self {
578 let mut bytes = [0; 32];
579 bytes[12..32].copy_from_slice(src.as_bytes());
580 ValueOrArray::Value(Some(H256::from(bytes)))
581 }
582}
583
584impl From<U256> for Topic {
585 fn from(src: U256) -> Self {
586 let mut bytes = [0; 32];
587 src.to_big_endian(&mut bytes);
588 ValueOrArray::Value(Some(H256::from(bytes)))
589 }
590}
591
592impl<T> Serialize for ValueOrArray<T>
593where
594 T: Serialize,
595{
596 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
597 where
598 S: Serializer,
599 {
600 match self {
601 ValueOrArray::Value(inner) => inner.serialize(serializer),
602 ValueOrArray::Array(inner) => inner.serialize(serializer),
603 }
604 }
605}
606
607impl<'a, T> Deserialize<'a> for ValueOrArray<T>
608where
609 T: DeserializeOwned,
610{
611 fn deserialize<D>(deserializer: D) -> Result<ValueOrArray<T>, D::Error>
612 where
613 D: Deserializer<'a>,
614 {
615 let value = serde_json::Value::deserialize(deserializer)?;
616
617 if value.is_null() {
618 return Ok(ValueOrArray::Array(Vec::new()))
619 }
620
621 #[derive(Deserialize)]
622 #[serde(untagged)]
623 enum Variadic<T> {
624 Value(T),
625 Array(Vec<T>),
626 }
627
628 match serde_json::from_value::<Variadic<T>>(value).map_err(|err| {
629 serde::de::Error::custom(format!("Invalid variadic value or array type: {err}"))
630 })? {
631 Variadic::Value(val) => Ok(ValueOrArray::Value(val)),
632 Variadic::Array(arr) => Ok(ValueOrArray::Array(arr)),
633 }
634 }
635}
636
637#[derive(Debug, Default)]
639pub struct FilteredParams {
640 pub filter: Option<Filter>,
641 pub flat_topics: Vec<ValueOrArray<Option<H256>>>,
642}
643
644impl FilteredParams {
645 pub fn new(filter: Option<Filter>) -> Self {
646 if let Some(filter) = filter {
647 let flat_topics = filter.flatten();
648 FilteredParams { filter: Some(filter), flat_topics }
649 } else {
650 Default::default()
651 }
652 }
653
654 pub fn address_filter(address: &Option<ValueOrArray<Address>>) -> BloomFilter {
656 address.as_ref().map(address_to_bloom_filter).unwrap_or_default()
657 }
658
659 pub fn topics_filter(topics: &Option<Vec<ValueOrArray<Option<H256>>>>) -> Vec<BloomFilter> {
661 let mut output = Vec::new();
662 if let Some(topics) = topics {
663 output.extend(topics.iter().map(topics_to_bloom_filter));
664 }
665 output
666 }
667
668 pub fn matches_topics(bloom: Bloom, topic_filters: &[BloomFilter]) -> bool {
670 if topic_filters.is_empty() {
671 return true
672 }
673
674 for filter in topic_filters.iter() {
676 let mut is_match = false;
677 for maybe_bloom in filter {
678 is_match = maybe_bloom.as_ref().map(|b| bloom.contains_bloom(b)).unwrap_or(true);
679 if !is_match {
680 break
681 }
682 }
683 if is_match {
684 return true
685 }
686 }
687 false
688 }
689
690 pub fn matches_address(bloom: Bloom, address_filter: &BloomFilter) -> bool {
692 if address_filter.is_empty() {
693 return true
694 } else {
695 for maybe_bloom in address_filter {
696 if maybe_bloom.as_ref().map(|b| bloom.contains_bloom(b)).unwrap_or(true) {
697 return true
698 }
699 }
700 }
701 false
702 }
703
704 pub fn replace(&self, log: &Log, topic: Topic) -> Option<Vec<H256>> {
706 let mut out: Vec<H256> = Vec::new();
707 match topic {
708 ValueOrArray::Value(value) => {
709 if let Some(value) = value {
710 out.push(value);
711 }
712 }
713 ValueOrArray::Array(value) => {
714 for (k, v) in value.into_iter().enumerate() {
715 if let Some(v) = v {
716 out.push(v);
717 } else {
718 out.push(log.topics[k]);
719 }
720 }
721 }
722 };
723 if out.is_empty() {
724 return None
725 }
726 Some(out)
727 }
728
729 pub fn filter_block_range(&self, block_number: u64) -> bool {
730 if self.filter.is_none() {
731 return true
732 }
733 let filter = self.filter.as_ref().unwrap();
734 let mut res = true;
735
736 if let Some(BlockNumber::Number(num)) = filter.block_option.get_from_block() {
737 if num.as_u64() > block_number {
738 res = false;
739 }
740 }
741
742 if let Some(to) = filter.block_option.get_to_block() {
743 match to {
744 BlockNumber::Number(num) => {
745 if num.as_u64() < block_number {
746 res = false;
747 }
748 }
749 BlockNumber::Earliest => {
750 res = false;
751 }
752 _ => {}
753 }
754 }
755 res
756 }
757
758 pub fn filter_block_hash(&self, block_hash: H256) -> bool {
759 if let Some(h) = self.filter.as_ref().and_then(|f| f.get_block_hash()) {
760 if h != block_hash {
761 return false
762 }
763 }
764 true
765 }
766
767 pub fn filter_address(&self, log: &Log) -> bool {
768 if let Some(input_address) = &self.filter.as_ref().and_then(|f| f.address.clone()) {
769 match input_address {
770 ValueOrArray::Value(x) => {
771 if log.address != *x {
772 return false
773 }
774 }
775 ValueOrArray::Array(x) => {
776 if x.is_empty() {
777 return true
778 }
779 if !x.contains(&log.address) {
780 return false
781 }
782 }
783 }
784 }
785 true
786 }
787
788 pub fn filter_topics(&self, log: &Log) -> bool {
789 let mut out: bool = true;
790 for topic in self.flat_topics.iter().cloned() {
791 match topic {
792 ValueOrArray::Value(single) => {
793 if let Some(single) = single {
794 if !log.topics.starts_with(&[single]) {
795 out = false;
796 }
797 }
798 }
799 ValueOrArray::Array(multi) => {
800 if multi.is_empty() {
801 out = true;
802 continue
803 }
804 let mut new_multi = multi;
806 while new_multi.iter().last().unwrap_or(&Some(H256::default())).is_none() {
807 new_multi.pop();
808 }
809 if new_multi.len() > log.topics.len() {
811 out = false;
812 break
813 }
814 let replaced: Option<Vec<H256>> =
815 self.replace(log, ValueOrArray::Array(new_multi));
816 if let Some(replaced) = replaced {
817 out = false;
818 if log.topics.starts_with(&replaced[..]) {
819 out = true;
820 break
821 }
822 }
823 }
824 }
825 }
826 out
827 }
828}
829
830fn topics_to_bloom_filter(topics: &ValueOrArray<Option<H256>>) -> BloomFilter {
831 let mut blooms = BloomFilter::new();
832 match topics {
833 ValueOrArray::Value(topic) => {
834 if let Some(topic) = topic {
835 let bloom: Bloom = BloomInput::Raw(topic.as_ref()).into();
836 blooms.push(Some(bloom));
837 } else {
838 blooms.push(None);
839 }
840 }
841 ValueOrArray::Array(topics) => {
842 if topics.is_empty() {
843 blooms.push(None);
844 } else {
845 for topic in topics.iter() {
846 if let Some(topic) = topic {
847 let bloom: Bloom = BloomInput::Raw(topic.as_ref()).into();
848 blooms.push(Some(bloom));
849 } else {
850 blooms.push(None);
851 }
852 }
853 }
854 }
855 }
856 blooms
857}
858
859fn address_to_bloom_filter(address: &ValueOrArray<Address>) -> BloomFilter {
860 let mut blooms = BloomFilter::new();
861 match address {
862 ValueOrArray::Value(address) => {
863 let bloom: Bloom = BloomInput::Raw(address.as_ref()).into();
864 blooms.push(Some(bloom))
865 }
866 ValueOrArray::Array(addresses) => {
867 if addresses.is_empty() {
868 blooms.push(None);
869 } else {
870 for address in addresses.iter() {
871 let bloom: Bloom = BloomInput::Raw(address.as_ref()).into();
872 blooms.push(Some(bloom));
873 }
874 }
875 }
876 }
877 blooms
878}
879
880#[cfg(test)]
881mod tests {
882 use super::*;
883 use crate::utils::serialize;
884 use serde_json::json;
885
886 #[test]
887 fn can_serde_value_or_array() {
888 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
889 struct Item {
890 value: ValueOrArray<U256>,
891 }
892
893 let item = Item { value: ValueOrArray::Value(U256::one()) };
894 let json = serde_json::to_value(item.clone()).unwrap();
895 let deserialized: Item = serde_json::from_value(json).unwrap();
896 assert_eq!(item, deserialized);
897
898 let item = Item { value: ValueOrArray::Array(vec![U256::one(), U256::zero()]) };
899 let json = serde_json::to_value(item.clone()).unwrap();
900 let deserialized: Item = serde_json::from_value(json).unwrap();
901 assert_eq!(item, deserialized);
902 }
903
904 #[test]
905 fn filter_serialization_test() {
906 let t1 = "9729a6fbefefc8f6005933898b13dc45c3a2c8b7".parse::<Address>().unwrap();
907 let t2 = H256::from([0; 32]);
908 let t3 = U256::from(123);
909
910 let t1_padded = H256::from(t1);
911 let t3_padded = H256::from({
912 let mut x = [0; 32];
913 x[31] = 123;
914 x
915 });
916
917 let event = "ValueChanged(address,string,string)";
918 let t0 = H256::from(keccak256(event.as_bytes()));
919 let addr: Address = "f817796F60D268A36a57b8D2dF1B97B14C0D0E1d".parse().unwrap();
920 let filter = Filter::new();
921
922 let ser = serialize(&filter);
923 assert_eq!(ser, json!({ "topics": [] }));
924
925 let filter = filter.address(ValueOrArray::Value(addr));
926
927 let ser = serialize(&filter);
928 assert_eq!(ser, json!({"address" : addr, "topics": []}));
929
930 let filter = filter.event(event);
931
932 let ser = serialize(&filter);
934 assert_eq!(ser, json!({ "address" : addr, "topics": [t0]}));
935
936 let ser = serialize(&filter.clone().topic1(t1));
938 assert_eq!(ser, json!({ "address" : addr, "topics": [t0, t1_padded]}));
939
940 let ser = serialize(&filter.clone().topic2(t2));
942 assert_eq!(ser, json!({ "address" : addr, "topics": [t0, null, t2]}));
943
944 let ser = serialize(&filter.clone().topic3(t3));
946 assert_eq!(ser, json!({ "address" : addr, "topics": [t0, null, null, t3_padded]}));
947
948 let ser = serialize(&filter.clone().topic1(t1).topic2(t2));
950 assert_eq!(ser, json!({ "address" : addr, "topics": [t0, t1_padded, t2]}));
951
952 let ser = serialize(&filter.clone().topic1(t1).topic3(t3));
954 assert_eq!(ser, json!({ "address" : addr, "topics": [t0, t1_padded, null, t3_padded]}));
955
956 let ser = serialize(&filter.clone().topic2(t2).topic3(t3));
958 assert_eq!(ser, json!({ "address" : addr, "topics": [t0, null, t2, t3_padded]}));
959
960 let ser = serialize(&filter.topic1(t1).topic2(t2).topic3(t3));
962 assert_eq!(ser, json!({ "address" : addr, "topics": [t0, t1_padded, t2, t3_padded]}));
963 }
964
965 fn build_bloom(address: Address, topic1: H256, topic2: H256) -> Bloom {
966 let mut block_bloom = Bloom::default();
967 block_bloom.accrue(BloomInput::Raw(&address[..]));
968 block_bloom.accrue(BloomInput::Raw(&topic1[..]));
969 block_bloom.accrue(BloomInput::Raw(&topic2[..]));
970 block_bloom
971 }
972
973 fn topic_filter(
974 topic1: H256,
975 topic2: H256,
976 topic3: H256,
977 ) -> (Filter, Option<Vec<ValueOrArray<Option<H256>>>>) {
978 let filter = Filter {
979 block_option: Default::default(),
980 address: None,
981 topics: [
982 Some(ValueOrArray::Value(Some(topic1))),
983 Some(ValueOrArray::Array(vec![Some(topic2), Some(topic3)])),
984 None,
985 None,
986 ],
987 };
988 let filtered_params = FilteredParams::new(Some(filter.clone()));
989
990 (filter, Some(filtered_params.flat_topics))
991 }
992
993 #[test]
994 fn can_detect_different_topics() {
995 let topic1 = H256::random();
996 let topic2 = H256::random();
997 let topic3 = H256::random();
998
999 let (_, topics) = topic_filter(topic1, topic2, topic3);
1000 let topics_bloom = FilteredParams::topics_filter(&topics);
1001 assert!(!FilteredParams::matches_topics(
1002 build_bloom(Address::random(), H256::random(), H256::random()),
1003 &topics_bloom
1004 ));
1005 }
1006
1007 #[test]
1008 fn can_match_topic() {
1009 let topic1 = H256::random();
1010 let topic2 = H256::random();
1011 let topic3 = H256::random();
1012
1013 let (_, topics) = topic_filter(topic1, topic2, topic3);
1014 let _topics_bloom = FilteredParams::topics_filter(&topics);
1015
1016 let topics_bloom = FilteredParams::topics_filter(&topics);
1017 assert!(FilteredParams::matches_topics(
1018 build_bloom(Address::random(), topic1, topic2),
1019 &topics_bloom
1020 ));
1021 }
1022
1023 #[test]
1024 fn can_match_empty_topics() {
1025 let filter =
1026 Filter { block_option: Default::default(), address: None, topics: Default::default() };
1027
1028 let filtered_params = FilteredParams::new(Some(filter));
1029 let topics = Some(filtered_params.flat_topics);
1030
1031 let topics_bloom = FilteredParams::topics_filter(&topics);
1032 assert!(FilteredParams::matches_topics(
1033 build_bloom(Address::random(), H256::random(), H256::random()),
1034 &topics_bloom
1035 ));
1036 }
1037
1038 #[test]
1039 fn can_match_address_and_topics() {
1040 let rng_address = Address::random();
1041 let topic1 = H256::random();
1042 let topic2 = H256::random();
1043 let topic3 = H256::random();
1044
1045 let filter = Filter {
1046 block_option: Default::default(),
1047 address: Some(ValueOrArray::Value(rng_address)),
1048 topics: [
1049 Some(ValueOrArray::Value(Some(topic1))),
1050 Some(ValueOrArray::Array(vec![Some(topic2), Some(topic3)])),
1051 None,
1052 None,
1053 ],
1054 };
1055 let filtered_params = FilteredParams::new(Some(filter.clone()));
1056 let topics = Some(filtered_params.flat_topics);
1057 let address_filter = FilteredParams::address_filter(&filter.address);
1058 let topics_filter = FilteredParams::topics_filter(&topics);
1059 assert!(
1060 FilteredParams::matches_address(
1061 build_bloom(rng_address, topic1, topic2),
1062 &address_filter
1063 ) && FilteredParams::matches_topics(
1064 build_bloom(rng_address, topic1, topic2),
1065 &topics_filter
1066 )
1067 );
1068 }
1069
1070 #[test]
1071 fn can_match_topics_wildcard() {
1072 let topic1 = H256::random();
1073 let topic2 = H256::random();
1074 let topic3 = H256::random();
1075
1076 let filter = Filter {
1077 block_option: Default::default(),
1078 address: None,
1079 topics: [None, Some(ValueOrArray::Array(vec![Some(topic2), Some(topic3)])), None, None],
1080 };
1081 let filtered_params = FilteredParams::new(Some(filter));
1082 let topics = Some(filtered_params.flat_topics);
1083 let topics_bloom = FilteredParams::topics_filter(&topics);
1084 assert!(FilteredParams::matches_topics(
1085 build_bloom(Address::random(), topic1, topic2),
1086 &topics_bloom
1087 ));
1088 }
1089
1090 #[test]
1091 fn can_match_topics_wildcard_mismatch() {
1092 let filter = Filter {
1093 block_option: Default::default(),
1094 address: None,
1095 topics: [
1096 None,
1097 Some(ValueOrArray::Array(vec![Some(H256::random()), Some(H256::random())])),
1098 None,
1099 None,
1100 ],
1101 };
1102 let filtered_params = FilteredParams::new(Some(filter));
1103 let topics_input = Some(filtered_params.flat_topics);
1104 let topics_bloom = FilteredParams::topics_filter(&topics_input);
1105 assert!(!FilteredParams::matches_topics(
1106 build_bloom(Address::random(), H256::random(), H256::random()),
1107 &topics_bloom
1108 ));
1109 }
1110
1111 #[test]
1112 fn can_match_address_filter() {
1113 let rng_address = Address::random();
1114 let filter = Filter {
1115 block_option: Default::default(),
1116 address: Some(ValueOrArray::Value(rng_address)),
1117 topics: Default::default(),
1118 };
1119 let address_bloom = FilteredParams::address_filter(&filter.address);
1120 assert!(FilteredParams::matches_address(
1121 build_bloom(rng_address, H256::random(), H256::random(),),
1122 &address_bloom
1123 ));
1124 }
1125
1126 #[test]
1127 fn can_detect_different_address() {
1128 let bloom_address = Address::random();
1129 let rng_address = Address::random();
1130 let filter = Filter {
1131 block_option: Default::default(),
1132 address: Some(ValueOrArray::Value(rng_address)),
1133 topics: Default::default(),
1134 };
1135 let address_bloom = FilteredParams::address_filter(&filter.address);
1136 assert!(!FilteredParams::matches_address(
1137 build_bloom(bloom_address, H256::random(), H256::random(),),
1138 &address_bloom
1139 ));
1140 }
1141
1142 #[test]
1143 fn can_convert_to_ethers_filter() {
1144 let json = json!(
1145 {
1146 "fromBlock": "0x429d3b",
1147 "toBlock": "0x429d3b",
1148 "address": "0xb59f67a8bff5d8cd03f6ac17265c550ed8f33907",
1149 "topics": [
1150 "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
1151 "0x00000000000000000000000000b46c2526e227482e2ebb8f4c69e4674d262e75",
1152 "0x00000000000000000000000054a2d42a40f51259dedd1978f6c118a0f0eff078"
1153 ]
1154 }
1155 );
1156
1157 let filter: Filter = serde_json::from_value(json).unwrap();
1158 assert_eq!(
1159 filter,
1160 Filter {
1161 block_option: FilterBlockOption::Range {
1162 from_block: Some(4365627u64.into()),
1163 to_block: Some(4365627u64.into()),
1164 },
1165 address: Some(ValueOrArray::Value(
1166 "0xb59f67a8bff5d8cd03f6ac17265c550ed8f33907".parse().unwrap()
1167 )),
1168 topics: [
1169 Some(ValueOrArray::Value(Some(
1170 "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
1171 .parse()
1172 .unwrap(),
1173 ))),
1174 Some(ValueOrArray::Value(Some(
1175 "0x00000000000000000000000000b46c2526e227482e2ebb8f4c69e4674d262e75"
1176 .parse()
1177 .unwrap(),
1178 ))),
1179 Some(ValueOrArray::Value(Some(
1180 "0x00000000000000000000000054a2d42a40f51259dedd1978f6c118a0f0eff078"
1181 .parse()
1182 .unwrap(),
1183 ))),
1184 None,
1185 ],
1186 }
1187 );
1188 }
1189
1190 #[test]
1191 fn can_convert_to_ethers_filter_with_null_fields() {
1192 let json = json!(
1193 {
1194 "fromBlock": "0x429d3b",
1195 "toBlock": "0x429d3b",
1196 "address": null,
1197 "topics": null
1198 }
1199 );
1200
1201 let filter: Filter = serde_json::from_value(json).unwrap();
1202 assert_eq!(
1203 filter,
1204 Filter {
1205 block_option: FilterBlockOption::Range {
1206 from_block: Some(4365627u64.into()),
1207 to_block: Some(4365627u64.into()),
1208 },
1209 address: None,
1210 topics: [None, None, None, None,],
1211 }
1212 );
1213 }
1214}