Using stream-fashion structures

This commit is contained in:
Enol Álvarez
2023-07-26 11:22:44 +02:00
parent 3678208dad
commit 73a819ad71
10 changed files with 132 additions and 225 deletions

View File

@@ -46,6 +46,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
[[package]] [[package]]
name = "bitvec" name = "bitvec"
version = "1.0.1" version = "1.0.1"
@@ -134,9 +140,9 @@ dependencies = [
[[package]] [[package]]
name = "either" name = "either"
version = "1.8.1" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]] [[package]]
name = "equivalent" name = "equivalent"
@@ -211,12 +217,9 @@ dependencies = [
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "1.9.0" version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
dependencies = [
"instant",
]
[[package]] [[package]]
name = "fixed-hash" name = "fixed-hash"
@@ -281,12 +284,6 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
[[package]] [[package]]
name = "hex" name = "hex"
version = "0.4.3" version = "0.4.3"
@@ -357,26 +354,6 @@ dependencies = [
"hashbrown 0.14.0", "hashbrown 0.14.0",
] ]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]]
name = "io-lifetimes"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi",
"libc",
"windows-sys",
]
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.10.5" version = "0.10.5"
@@ -415,9 +392,9 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.3.8" version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0"
[[package]] [[package]]
name = "log" name = "log"
@@ -460,9 +437,9 @@ dependencies = [
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.15" version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
@@ -628,9 +605,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.31" version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@@ -677,7 +654,7 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.3.2",
] ]
[[package]] [[package]]
@@ -727,13 +704,12 @@ checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.37.23" version = "0.38.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.3.3",
"errno", "errno",
"io-lifetimes",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys",
"windows-sys", "windows-sys",
@@ -747,22 +723,22 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.171" version = "1.0.175"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.171" version = "1.0.175"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.26", "syn 2.0.27",
] ]
[[package]] [[package]]
@@ -805,9 +781,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "substreams" name = "substreams"
version = "0.5.8" version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ea94f238b54b075ad17894537bdcc20d5fc65cdc199bf1594c9ecfdc6454840"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bigdecimal", "bigdecimal",
@@ -825,9 +799,9 @@ dependencies = [
[[package]] [[package]]
name = "substreams-ethereum" name = "substreams-ethereum"
version = "0.9.2" version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf3a20ea2cf8648b88983efddada20d7f5af7dce834e0a7232cd0c7b02b1aa32" checksum = "c0bd6c3ecb69e76111515d8087080ce7a750f41df79de221d24ab76bc3efe81e"
dependencies = [ dependencies = [
"getrandom", "getrandom",
"num-bigint", "num-bigint",
@@ -839,9 +813,9 @@ dependencies = [
[[package]] [[package]]
name = "substreams-ethereum-abigen" name = "substreams-ethereum-abigen"
version = "0.9.2" version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37193a8fbbaa8659ee2ca008380d5db00109e60385a825b7f82d5864f054a01e" checksum = "894803ed2422e63afac798ae1370faf6897d9200b53c03aa53b4945ea28cdc3d"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"ethabi", "ethabi",
@@ -856,9 +830,9 @@ dependencies = [
[[package]] [[package]]
name = "substreams-ethereum-core" name = "substreams-ethereum-core"
version = "0.9.2" version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4caa3329aa29a4584906f2624b836ec81ef61f9ee51da821ac718354e6199d05" checksum = "49a7a83144082aafd061f36bc68a20f1a2b3b8774ec58cd0dabd222a3f606a0c"
dependencies = [ dependencies = [
"bigdecimal", "bigdecimal",
"ethabi", "ethabi",
@@ -872,9 +846,9 @@ dependencies = [
[[package]] [[package]]
name = "substreams-ethereum-derive" name = "substreams-ethereum-derive"
version = "0.9.2" version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8deeda1cdf7dc2b2b66d66b8d2ca1210eb13aac9c62bc4a693e7656c2fd82780" checksum = "ac19d40bbdf62261b6acca3a7e43f8ad68b5bc76ca41a8822988c757b2b0d9e9"
dependencies = [ dependencies = [
"ethabi", "ethabi",
"heck", "heck",
@@ -904,9 +878,7 @@ dependencies = [
[[package]] [[package]]
name = "substreams-macro" name = "substreams-macro"
version = "0.5.8" version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c9df3ebfeefa8958b1de17f7e9e80f9b1d9a78cbe9114716a872a52b60b8343"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -927,9 +899,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.26" version = "2.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -944,11 +916,10 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.6.0" version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998"
dependencies = [ dependencies = [
"autocfg",
"cfg-if", "cfg-if",
"fastrand", "fastrand",
"redox_syscall", "redox_syscall",
@@ -958,22 +929,22 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.43" version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.43" version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.26", "syn 2.0.27",
] ]
[[package]] [[package]]
@@ -1123,9 +1094,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.5.0" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]

View File

@@ -16,21 +16,21 @@ hex-literal = "0.3"
num-bigint = "0.4" num-bigint = "0.4"
prost = "0.11" prost = "0.11"
# Use latest from https://crates.io/crates/substreams # Use latest from https://crates.io/crates/substreams
substreams = "0.5" substreams = "0.5.9"
# Use latest from https://crates.io/crates/substreams-ethereum # Use latest from https://crates.io/crates/substreams-ethereum
substreams-ethereum = "0.9" substreams-ethereum = "0.9"
serde_qs = "0.12.0" serde_qs = "0.12.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
anyhow = "1.0"
# Required so that ethabi > ethereum-types build correctly under wasm32-unknown-unknown # Required so that ethabi > ethereum-types build correctly under wasm32-unknown-unknown
[target.wasm32-unknown-unknown.dependencies] [target.wasm32-unknown-unknown.dependencies]
getrandom = { version = "0.2", features = ["custom"] } getrandom = { version = "0.2", features = ["custom"] }
[build-dependencies]
anyhow = "1"
substreams-ethereum = "0.9"
[profile.release] [profile.release]
lto = true lto = true
opt-level = 's' opt-level = 's'
strip = "debuginfo" strip = "debuginfo"
[patch.crates-io]
substreams = { path = "/Users/enolalvarezdeprado/Documents/streamingfast/substreams-rs/substreams" }

View File

@@ -6,6 +6,6 @@ build:
protogen: protogen:
substreams protogen ./substreams.yaml --exclude-paths="sf/substreams,google" substreams protogen ./substreams.yaml --exclude-paths="sf/substreams,google"
.PHONY: package .PHONY: pack
package: build pack: build
substreams pack substreams.yaml substreams pack substreams.yaml

View File

@@ -78,7 +78,7 @@ To run this module, you must provide a transaction hash, so that Substreams can
The `4faa877df84080a9d98b1e28294c4680bb141ec27a1a5dee009c3e02dfa65ab7` transaction is at block number `17712040`. In order to avoid iterating over the full blockchain, the following command starts searching at block number `17712038`. The `4faa877df84080a9d98b1e28294c4680bb141ec27a1a5dee009c3e02dfa65ab7` transaction is at block number `17712040`. In order to avoid iterating over the full blockchain, the following command starts searching at block number `17712038`.
```bash ```bash
> substreams run -e mainnet.eth.streamingfast.io:443 substreams.yaml map_filter_transaction --start-block 17712038 --stop-block +10 > substreams run -e mainnet.eth.streamingfast.io:443 substreams.yaml map_filter_transactions --start-block 17712038 --stop-block +10
Connected (trace ID 9dce06621a0ec353213adeaf9f10ef79) Connected (trace ID 9dce06621a0ec353213adeaf9f10ef79)
Progress messages received: 0 (0/sec) Progress messages received: 0 (0/sec)
Backprocessing history up to requested target block 17712038: Backprocessing history up to requested target block 17712038:

View File

@@ -1,7 +1,7 @@
mod pb;
mod map_block_meta; mod map_block_meta;
mod map_filter_transactions;
mod map_contract_events; mod map_contract_events;
mod map_filter_transactions;
mod pb;
mod util; mod util;
substreams_ethereum::init!(); substreams_ethereum::init!();

View File

@@ -1,17 +1,14 @@
use substreams_ethereum::pb::eth::v2::Block;
use crate::pb::eth::block_meta::v1::BlockMeta; use crate::pb::eth::block_meta::v1::BlockMeta;
use substreams::Hex; use substreams::Hex;
use substreams_ethereum::pb::eth::v2::Block;
#[substreams::handlers::map] #[substreams::handlers::map]
fn map_block_meta(blk: Block) -> Result<BlockMeta, substreams::errors::Error> { fn map_block_meta(blk: Block) -> Result<BlockMeta, substreams::errors::Error> {
let header = blk.header.as_ref().unwrap(); let header = blk.header.as_ref().unwrap();
let hash_string = Hex(&blk.hash).to_string();
let parent_hash_string = Hex(&header.parent_hash).to_string();
Ok(BlockMeta { Ok(BlockMeta {
number: blk.number, number: blk.number,
hash: hash_string, hash: Hex::encode(&blk.hash),
parent_hash: parent_hash_string parent_hash: Hex::encode(&header.parent_hash),
}) })
} }

View File

@@ -1,73 +1,32 @@
use crate::pb::eth::event::v1::Events;
use crate::pb::eth::event::v1::Event; use crate::pb::eth::event::v1::Event;
use substreams_ethereum::pb::eth::v2::Block; use crate::pb::eth::event::v1::Events;
use substreams::Hex;
use substreams_ethereum::pb::eth::v2::Log;
use substreams_ethereum::pb::eth::v2::TransactionTrace;
use substreams::errors::Error;
use crate::util; use crate::util;
use anyhow::Ok;
use substreams::errors::Error;
use substreams::Hex;
use substreams_ethereum::pb::eth::v2::Block;
use anyhow::anyhow;
#[substreams::handlers::map] #[substreams::handlers::map]
fn map_contract_events(contract_address: String, blk: Block) -> Result<Events, Error> { fn map_contract_events(contract_address: String, blk: Block) -> Result<Events, Error> {
let error = verify_parameter(&contract_address); verify_parameter(&contract_address)?;
if error.is_some() {
return Err(error.unwrap()); let events: Vec<Event> = blk.logs()
} .filter(| log| log.address().to_vec() == Hex::decode(&contract_address).expect("already validated"))
.map(|log| Event {
let mut events: Vec<Event> = Vec::new(); address: Hex::encode(log.address()),
let contract_address_as_vec = match Hex::decode(&contract_address) { topics: log.topics().into_iter().map(| topic| Hex::encode(topic)).collect(),
Ok(address) => address, tx_hash: Hex::encode(&log.receipt.transaction.hash)
Err(error) => return Err(Error::Unexpected(error.to_string())), })
}; .collect();
for transaction in &blk.transaction_traces {
if transaction.to == contract_address_as_vec {
let transaction_events = get_transaction_events(&transaction);
events.extend(transaction_events);
}
}
Ok(Events { events }) Ok(Events { events })
} }
fn verify_parameter(contract_address: &String) -> Option<Error> { fn verify_parameter(address: &String) -> Result<(), Error> {
if !util::is_address_valid(contract_address) { if !util::is_address_valid(&address) {
return Some(Error::Unexpected(String::from("Contract address is not valid"))) return Err(anyhow!("Contract address is not valid"));
} }
return None return Ok(());
}
fn get_transaction_events(transaction: &TransactionTrace) -> Vec<Event> {
let mut transaction_events: Vec<Event> = Vec::new();
for log in &transaction.receipt().receipt.logs {
let address = util::hexadecimal_to_string(&log.address);
let topics = get_log_topics(&log);
let event = create_event_from(address, topics, util::hexadecimal_to_string(&transaction.hash));
transaction_events.push(event)
}
return transaction_events;
}
fn get_log_topics(log: &Log) -> Vec<String> {
let mut topics: Vec<String> = Vec::new();
for topic in &log.topics {
let topic_string = util::hexadecimal_to_string(topic);
topics.push(topic_string)
}
return topics;
}
fn create_event_from(address: String, topics: Vec<String>, hash: String) -> Event {
return Event {
address,
topics,
tx_hash: hash
}
} }

View File

@@ -1,77 +1,72 @@
use substreams_ethereum::pb::eth::v2::{Block, TransactionTraceStatus};
use crate::pb::eth::transaction::v1::{Transaction, Transactions}; use crate::pb::eth::transaction::v1::{Transaction, Transactions};
use serde::Deserialize;
use substreams::errors::Error;
use crate::util; use crate::util;
use serde::Deserialize;
use substreams::Hex;
use substreams_ethereum::pb::eth::v2::{Block, TransactionTraceStatus, TransactionTrace};
use anyhow::anyhow;
#[derive(Deserialize)] #[derive(Deserialize)]
struct TransactionFilterParams { struct TransactionFilterParams {
hash: Option<String>,
to: Option<String>, to: Option<String>,
from: Option<String> from: Option<String>,
} }
#[substreams::handlers::map] #[substreams::handlers::map]
pub fn map_filter_transactions(params: String, blk: Block) -> Result<Transactions, Vec<substreams::errors::Error>> { fn map_filter_transactions(params: String, blk: Block) -> Result<Transactions, Vec<substreams::errors::Error>> {
let filters: TransactionFilterParams = serde_qs::from_str(&params).unwrap(); let filters: TransactionFilterParams = serde_qs::from_str(&params).unwrap();
let errors = verify_filter_params(&filters); verify_filter_params(&filters)?;
let transactions: Vec<Transaction> = blk.transactions()
.filter(|trans| apply_filter(&trans, &filters))
.map(|trans| Transaction {
from: Hex::encode(&trans.from),
to: Hex::encode(&trans.to),
hash: Hex::encode(&trans.hash),
}).collect();
Ok(Transactions {
transactions,
})
}
fn verify_filter_params(params: &TransactionFilterParams) -> Result<(), Vec<substreams::errors::Error>> {
let mut errors: Vec<substreams::errors::Error> = Vec::new();
if params.from.is_some() && !util::is_address_valid(&params.from.as_ref().unwrap()) {
errors.push(anyhow!("'from' address is not valid"));
}
if params.to.is_some() && !util::is_address_valid(&params.to.as_ref().unwrap()) {
errors.push(anyhow!("'to' address is not valid"));
}
if errors.len() > 0 { if errors.len() > 0 {
return Err(errors) return Err(errors)
} }
let mut filtered_transactions: Vec<Transaction> = Vec::new(); return Ok(())
for transaction in &blk.transaction_traces {
let tx_hash = util::hexadecimal_to_string(&transaction.hash);
let tx_from = util::hexadecimal_to_string(&transaction.from);
let tx_to = util::hexadecimal_to_string(&transaction.to);
let mut current_transaction_filtered = true;
if !filter_by_parameter(&filters.hash, &tx_hash) ||
!filter_by_parameter(&filters.from, &tx_from) ||
!filter_by_parameter(&filters.to, &tx_to) ||
transaction.status != (TransactionTraceStatus::Succeeded as i32) {
current_transaction_filtered = false
}
if current_transaction_filtered {
let trans = Transaction { from: tx_from, to: tx_to, hash: tx_hash };
filtered_transactions.push(trans)
}
}
Ok(Transactions { transactions: filtered_transactions })
} }
fn verify_filter_params(params: &TransactionFilterParams) -> Vec<substreams::errors::Error> { fn apply_filter(transaction: &TransactionTrace, filters: &TransactionFilterParams) -> bool {
let mut errors: Vec<substreams::errors::Error> = Vec::new(); if !filter_by_parameter(&filters.from, &transaction.from)
|| !filter_by_parameter(&filters.to, &transaction.to)
if params.hash.is_some() || transaction.status != (TransactionTraceStatus::Succeeded as i32) {
&& !util::is_transaction_hash_valid(&params.hash.as_ref().unwrap()) { return false;
errors.push(Error::Unexpected(String::from("Transaction hash is not valid")));
} }
if params.from.is_some() return true;
&& !util::is_address_valid(&params.from.as_ref().unwrap()) {
errors.push(Error::Unexpected(String::from("'from' address is not valid")));
}
if params.to.is_some()
&& !util::is_address_valid(&params.to.as_ref().unwrap()) {
errors.push(Error::Unexpected(String::from("'to' address is not valid")));
}
return errors;
} }
fn filter_by_parameter(parameter: &Option<String>, transaction_field: &String) -> bool { fn filter_by_parameter(parameter: &Option<String>, transaction_field: &Vec<u8>) -> bool {
if parameter.is_none() { if parameter.is_none() {
return true; return true;
} }
if parameter.as_ref().unwrap() == transaction_field { let parameter_as_vec = &Hex::decode(parameter.as_ref().unwrap()).expect("already verified");
return true if parameter_as_vec == transaction_field {
return true;
} }
return false; return false;
} }

View File

@@ -1,23 +1,8 @@
use substreams::Hex; pub fn is_address_valid(address: &String) -> bool {
// An address is always 40 hexadecimal characters (or 2 more character with 0x prefix)
pub fn hexadecimal_to_string(hex: &Vec<u8>) -> String { if address.len() != 40 && address.len() != 42 {
return Hex::encode(hex);
}
pub fn is_transaction_hash_valid(hash: &String) -> bool {
// A transaction hash is always 64 hexadecimal characters
if hash.len() != 64 {
return false; return false;
} }
return true;
}
pub fn is_address_valid(address: &String) -> bool {
// An address is always 40 hexadecimal characters
if address.len() != 40 {
return false;
}
return true; return true;
} }

View File

@@ -39,5 +39,5 @@ modules:
type: proto:eth.event.v1.Events type: proto:eth.event.v1.Events
params: params:
map_filter_transactions: "to=dac17f958d2ee523a2206206994597c13d831ec7&from=46340b20830761efd32832a74d7169b29feb9758" map_filter_transactions: "to=0xae0Ee0A63A2cE6BaeEFFE56e7714FB4EFE48D419"
map_contract_events: "bc4ca0eda7647a8ab7c2061c2e118a18a936f13d" map_contract_events: "0x6e60bCdF52078A250932CF9FeC174c5F67348845"