This commit is contained in:
Enol Álvarez
2023-07-27 19:44:06 +02:00
parent 38c52d9a2a
commit 0618138987
4 changed files with 52 additions and 29 deletions

View File

@@ -0,0 +1 @@
max_width = 120

View File

@@ -1,22 +1,23 @@
use crate::pb::eth::event::v1::Event;
use crate::pb::eth::event::v1::Events;
use crate::util;
use anyhow::anyhow;
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> {
verify_parameter(&contract_address)?;
let events: Vec<Event> = blk.logs()
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)
topics: log.topics().into_iter().map(Hex::encode).collect(),
tx_hash: Hex::encode(&log.receipt.transaction.hash),
})
.collect();
@@ -25,7 +26,7 @@ fn map_contract_events(contract_address: String, blk: Block) -> Result<Events, E
fn verify_parameter(address: &String) -> Result<(), Error> {
if !util::is_address_valid(&address) {
return Err(anyhow!("Contract address is not valid"));
return Err(anyhow!("Contract address ({}) is not valid", address));
}
Ok(())

View File

@@ -1,9 +1,9 @@
use crate::pb::eth::transaction::v1::{Transaction, Transactions};
use crate::util;
use anyhow::anyhow;
use serde::Deserialize;
use substreams::Hex;
use substreams_ethereum::pb::eth::v2::{Block, TransactionTraceStatus, TransactionTrace};
use anyhow::anyhow;
use substreams_ethereum::pb::eth::v2::{Block, TransactionTrace, TransactionTraceStatus};
#[derive(Deserialize)]
struct TransactionFilterParams {
@@ -13,36 +13,54 @@ struct TransactionFilterParams {
#[substreams::handlers::map]
fn map_filter_transactions(params: String, blk: Block) -> Result<Transactions, Vec<substreams::errors::Error>> {
let filters: TransactionFilterParams = serde_qs::from_str(&params).unwrap();
verify_filter_params(&filters)?;
let filters = parse_filters_from_params(params)?;
let transactions: Vec<Transaction> = blk.transactions()
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,
})
.collect();
Ok(Transactions { transactions })
}
fn verify_filter_params(params: &TransactionFilterParams) -> Result<(), Vec<substreams::errors::Error>> {
fn parse_filters_from_params(params: String) -> Result<TransactionFilterParams, Vec<substreams::errors::Error>> {
let parsed_result = serde_qs::from_str(&params);
if parsed_result.is_err() {
return Err(Vec::from([anyhow!("Unpexcted error while parsing parameters")]));
}
let filters = parsed_result.unwrap();
verify_filters(&filters)?;
Ok(filters)
}
fn verify_filters(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"));
let from = params.from.as_ref().unwrap();
if !util::is_address_valid(from) {
errors.push(anyhow!("'from' address ({}) is not valid", from));
}
}
if params.to.is_some() && !util::is_address_valid(&params.to.as_ref().unwrap()) {
errors.push(anyhow!("'to' address is not valid"));
let to = params.to.as_ref().unwrap();
if !util::is_address_valid(to) {
errors.push(anyhow!("'to' address ({}) is not valid", to));
}
}
if errors.len() > 0 {
return Err(errors)
return Err(errors);
}
Ok(())
@@ -51,7 +69,8 @@ fn verify_filter_params(params: &TransactionFilterParams) -> Result<(), Vec<subs
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) {
|| transaction.status != (TransactionTraceStatus::Succeeded as i32)
{
return false;
}
@@ -64,7 +83,7 @@ fn filter_by_parameter(parameter: &Option<String>, transaction_field: &Vec<u8>)
}
let parameter_as_vec = &Hex::decode(parameter.as_ref().unwrap()).expect("already verified");
if parameter_as_vec == transaction_field {
if transaction_field == parameter_as_vec {
return true;
}

View File

@@ -39,5 +39,7 @@ modules:
type: proto:eth.event.v1.Events
params:
# Filtering transactions with to = 0xdAC17F958D2ee523a2206206994597C13D831ec7 (USDT contract address)
map_filter_transactions: "to=0xdAC17F958D2ee523a2206206994597C13D831ec7"
# Getting the logs of the BoredApeYachtClub smart contract
map_contract_events: "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"