Using stream-fashion structures
This commit is contained in:
121
ethereum-explorer/Cargo.lock
generated
121
ethereum-explorer/Cargo.lock
generated
@@ -46,6 +46,12 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "1.0.1"
|
||||
@@ -134,9 +140,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.1"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
@@ -211,12 +217,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.9.0"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
|
||||
|
||||
[[package]]
|
||||
name = "fixed-hash"
|
||||
@@ -281,12 +284,6 @@ version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
@@ -357,26 +354,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
@@ -415,9 +392,9 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.3.8"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
||||
checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
@@ -460,9 +437,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
@@ -628,9 +605,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.31"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0"
|
||||
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -677,7 +654,7 @@ version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -727,13 +704,12 @@ checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.23"
|
||||
version = "0.38.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06"
|
||||
checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.3.3",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
@@ -747,22 +723,22 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.171"
|
||||
version = "1.0.175"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
|
||||
checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.171"
|
||||
version = "1.0.175"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682"
|
||||
checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -805,9 +781,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "substreams"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ea94f238b54b075ad17894537bdcc20d5fc65cdc199bf1594c9ecfdc6454840"
|
||||
version = "0.5.9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bigdecimal",
|
||||
@@ -825,9 +799,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "substreams-ethereum"
|
||||
version = "0.9.2"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf3a20ea2cf8648b88983efddada20d7f5af7dce834e0a7232cd0c7b02b1aa32"
|
||||
checksum = "c0bd6c3ecb69e76111515d8087080ce7a750f41df79de221d24ab76bc3efe81e"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"num-bigint",
|
||||
@@ -839,9 +813,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "substreams-ethereum-abigen"
|
||||
version = "0.9.2"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37193a8fbbaa8659ee2ca008380d5db00109e60385a825b7f82d5864f054a01e"
|
||||
checksum = "894803ed2422e63afac798ae1370faf6897d9200b53c03aa53b4945ea28cdc3d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ethabi",
|
||||
@@ -856,9 +830,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "substreams-ethereum-core"
|
||||
version = "0.9.2"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4caa3329aa29a4584906f2624b836ec81ef61f9ee51da821ac718354e6199d05"
|
||||
checksum = "49a7a83144082aafd061f36bc68a20f1a2b3b8774ec58cd0dabd222a3f606a0c"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"ethabi",
|
||||
@@ -872,9 +846,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "substreams-ethereum-derive"
|
||||
version = "0.9.2"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8deeda1cdf7dc2b2b66d66b8d2ca1210eb13aac9c62bc4a693e7656c2fd82780"
|
||||
checksum = "ac19d40bbdf62261b6acca3a7e43f8ad68b5bc76ca41a8822988c757b2b0d9e9"
|
||||
dependencies = [
|
||||
"ethabi",
|
||||
"heck",
|
||||
@@ -904,9 +878,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "substreams-macro"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c9df3ebfeefa8958b1de17f7e9e80f9b1d9a78cbe9114716a872a52b60b8343"
|
||||
version = "0.5.9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -927,9 +899,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.26"
|
||||
version = "2.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970"
|
||||
checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -944,11 +916,10 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.6.0"
|
||||
version = "3.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
|
||||
checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"redox_syscall",
|
||||
@@ -958,22 +929,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.43"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42"
|
||||
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.43"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f"
|
||||
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.26",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1123,9 +1094,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7"
|
||||
checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
@@ -16,21 +16,21 @@ hex-literal = "0.3"
|
||||
num-bigint = "0.4"
|
||||
prost = "0.11"
|
||||
# Use latest from https://crates.io/crates/substreams
|
||||
substreams = "0.5"
|
||||
substreams = "0.5.9"
|
||||
# Use latest from https://crates.io/crates/substreams-ethereum
|
||||
substreams-ethereum = "0.9"
|
||||
serde_qs = "0.12.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
anyhow = "1.0"
|
||||
|
||||
# Required so that ethabi > ethereum-types build correctly under wasm32-unknown-unknown
|
||||
[target.wasm32-unknown-unknown.dependencies]
|
||||
getrandom = { version = "0.2", features = ["custom"] }
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1"
|
||||
substreams-ethereum = "0.9"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
opt-level = 's'
|
||||
strip = "debuginfo"
|
||||
strip = "debuginfo"
|
||||
|
||||
[patch.crates-io]
|
||||
substreams = { path = "/Users/enolalvarezdeprado/Documents/streamingfast/substreams-rs/substreams" }
|
||||
@@ -6,6 +6,6 @@ build:
|
||||
protogen:
|
||||
substreams protogen ./substreams.yaml --exclude-paths="sf/substreams,google"
|
||||
|
||||
.PHONY: package
|
||||
package: build
|
||||
.PHONY: pack
|
||||
pack: build
|
||||
substreams pack substreams.yaml
|
||||
|
||||
@@ -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`.
|
||||
|
||||
```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)
|
||||
Progress messages received: 0 (0/sec)
|
||||
Backprocessing history up to requested target block 17712038:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
mod pb;
|
||||
mod map_block_meta;
|
||||
mod map_filter_transactions;
|
||||
mod map_contract_events;
|
||||
mod map_filter_transactions;
|
||||
mod pb;
|
||||
mod util;
|
||||
|
||||
substreams_ethereum::init!();
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
use substreams_ethereum::pb::eth::v2::Block;
|
||||
use crate::pb::eth::block_meta::v1::BlockMeta;
|
||||
use substreams::Hex;
|
||||
use substreams_ethereum::pb::eth::v2::Block;
|
||||
|
||||
#[substreams::handlers::map]
|
||||
fn map_block_meta(blk: Block) -> Result<BlockMeta, substreams::errors::Error> {
|
||||
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 {
|
||||
number: blk.number,
|
||||
hash: hash_string,
|
||||
parent_hash: parent_hash_string
|
||||
number: blk.number,
|
||||
hash: Hex::encode(&blk.hash),
|
||||
parent_hash: Hex::encode(&header.parent_hash),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,73 +1,32 @@
|
||||
use crate::pb::eth::event::v1::Events;
|
||||
use crate::pb::eth::event::v1::Event;
|
||||
use substreams_ethereum::pb::eth::v2::Block;
|
||||
use substreams::Hex;
|
||||
use substreams_ethereum::pb::eth::v2::Log;
|
||||
use substreams_ethereum::pb::eth::v2::TransactionTrace;
|
||||
use substreams::errors::Error;
|
||||
use crate::pb::eth::event::v1::Events;
|
||||
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]
|
||||
fn map_contract_events(contract_address: String, blk: Block) -> Result<Events, Error> {
|
||||
let error = verify_parameter(&contract_address);
|
||||
if error.is_some() {
|
||||
return Err(error.unwrap());
|
||||
}
|
||||
|
||||
let mut events: Vec<Event> = Vec::new();
|
||||
let contract_address_as_vec = match Hex::decode(&contract_address) {
|
||||
Ok(address) => address,
|
||||
Err(error) => return Err(Error::Unexpected(error.to_string())),
|
||||
};
|
||||
|
||||
for transaction in &blk.transaction_traces {
|
||||
if transaction.to == contract_address_as_vec {
|
||||
let transaction_events = get_transaction_events(&transaction);
|
||||
events.extend(transaction_events);
|
||||
}
|
||||
}
|
||||
verify_parameter(&contract_address)?;
|
||||
|
||||
let events: Vec<Event> = blk.logs()
|
||||
.filter(| log| log.address().to_vec() == Hex::decode(&contract_address).expect("already validated"))
|
||||
.map(|log| Event {
|
||||
address: Hex::encode(log.address()),
|
||||
topics: log.topics().into_iter().map(| topic| Hex::encode(topic)).collect(),
|
||||
tx_hash: Hex::encode(&log.receipt.transaction.hash)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(Events { events })
|
||||
}
|
||||
|
||||
fn verify_parameter(contract_address: &String) -> Option<Error> {
|
||||
if !util::is_address_valid(contract_address) {
|
||||
return Some(Error::Unexpected(String::from("Contract address is not valid")))
|
||||
fn verify_parameter(address: &String) -> Result<(), Error> {
|
||||
if !util::is_address_valid(&address) {
|
||||
return Err(anyhow!("Contract address is not valid"));
|
||||
}
|
||||
|
||||
return None
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
@@ -1,77 +1,72 @@
|
||||
use substreams_ethereum::pb::eth::v2::{Block, TransactionTraceStatus};
|
||||
use crate::pb::eth::transaction::v1::{Transaction, Transactions};
|
||||
use serde::Deserialize;
|
||||
use substreams::errors::Error;
|
||||
use crate::util;
|
||||
use serde::Deserialize;
|
||||
use substreams::Hex;
|
||||
use substreams_ethereum::pb::eth::v2::{Block, TransactionTraceStatus, TransactionTrace};
|
||||
use anyhow::anyhow;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct TransactionFilterParams {
|
||||
hash: Option<String>,
|
||||
to: Option<String>,
|
||||
from: Option<String>
|
||||
from: Option<String>,
|
||||
}
|
||||
|
||||
#[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(¶ms).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(¶ms.from.as_ref().unwrap()) {
|
||||
errors.push(anyhow!("'from' address is not valid"));
|
||||
}
|
||||
|
||||
if params.to.is_some() && !util::is_address_valid(¶ms.to.as_ref().unwrap()) {
|
||||
errors.push(anyhow!("'to' address is not valid"));
|
||||
}
|
||||
|
||||
if errors.len() > 0 {
|
||||
return Err(errors)
|
||||
}
|
||||
|
||||
let mut filtered_transactions: Vec<Transaction> = Vec::new();
|
||||
|
||||
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 })
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
fn verify_filter_params(params: &TransactionFilterParams) -> Vec<substreams::errors::Error> {
|
||||
let mut errors: Vec<substreams::errors::Error> = Vec::new();
|
||||
|
||||
if params.hash.is_some()
|
||||
&& !util::is_transaction_hash_valid(¶ms.hash.as_ref().unwrap()) {
|
||||
errors.push(Error::Unexpected(String::from("Transaction hash is not valid")));
|
||||
fn apply_filter(transaction: &TransactionTrace, filters: &TransactionFilterParams) -> bool {
|
||||
if !filter_by_parameter(&filters.from, &transaction.from)
|
||||
|| !filter_by_parameter(&filters.to, &transaction.to)
|
||||
|| transaction.status != (TransactionTraceStatus::Succeeded as i32) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if params.from.is_some()
|
||||
&& !util::is_address_valid(¶ms.from.as_ref().unwrap()) {
|
||||
errors.push(Error::Unexpected(String::from("'from' address is not valid")));
|
||||
}
|
||||
|
||||
if params.to.is_some()
|
||||
&& !util::is_address_valid(¶ms.to.as_ref().unwrap()) {
|
||||
errors.push(Error::Unexpected(String::from("'to' address is not valid")));
|
||||
}
|
||||
|
||||
return errors;
|
||||
return true;
|
||||
}
|
||||
|
||||
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() {
|
||||
return true;
|
||||
}
|
||||
|
||||
if parameter.as_ref().unwrap() == transaction_field {
|
||||
return true
|
||||
let parameter_as_vec = &Hex::decode(parameter.as_ref().unwrap()).expect("already verified");
|
||||
if parameter_as_vec == transaction_field {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,8 @@
|
||||
use substreams::Hex;
|
||||
|
||||
pub fn hexadecimal_to_string(hex: &Vec<u8>) -> String {
|
||||
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 {
|
||||
pub fn is_address_valid(address: &String) -> bool {
|
||||
// An address is always 40 hexadecimal characters (or 2 more character with 0x prefix)
|
||||
if address.len() != 40 && address.len() != 42 {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -39,5 +39,5 @@ modules:
|
||||
type: proto:eth.event.v1.Events
|
||||
|
||||
params:
|
||||
map_filter_transactions: "to=dac17f958d2ee523a2206206994597c13d831ec7&from=46340b20830761efd32832a74d7169b29feb9758"
|
||||
map_contract_events: "bc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
|
||||
map_filter_transactions: "to=0xae0Ee0A63A2cE6BaeEFFE56e7714FB4EFE48D419"
|
||||
map_contract_events: "0x6e60bCdF52078A250932CF9FeC174c5F67348845"
|
||||
Reference in New Issue
Block a user