Add tycho pb type constructors.
This allows us to remove a lot of unnecessary boilerplate code.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use substreams_ethereum::pb::eth;
|
||||
use substreams_ethereum::pb::eth::v2::StorageChange;
|
||||
|
||||
use crate::pb::tycho::evm::v1::{self as tycho};
|
||||
|
||||
@@ -15,6 +16,12 @@ struct SlotValue {
|
||||
start_value: Vec<u8>,
|
||||
}
|
||||
|
||||
impl From<&StorageChange> for SlotValue {
|
||||
fn from(change: &StorageChange) -> Self {
|
||||
Self { new_value: change.new_value.clone(), start_value: change.old_value.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
impl SlotValue {
|
||||
fn has_changed(&self) -> bool {
|
||||
self.start_value != self.new_value
|
||||
@@ -30,6 +37,22 @@ struct InterimContractChange {
|
||||
change: tycho::ChangeType,
|
||||
}
|
||||
|
||||
impl InterimContractChange {
|
||||
fn new(address: &[u8], creation: bool) -> Self {
|
||||
Self {
|
||||
address: address.to_vec(),
|
||||
balance: vec![],
|
||||
code: vec![],
|
||||
slots: Default::default(),
|
||||
change: if creation {
|
||||
tycho::ChangeType::Creation.into()
|
||||
} else {
|
||||
tycho::ChangeType::Update.into()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InterimContractChange> for tycho::ContractChange {
|
||||
fn from(value: InterimContractChange) -> Self {
|
||||
tycho::ContractChange {
|
||||
@@ -90,28 +113,20 @@ pub fn extract_contract_changes<F: Fn(&[u8]) -> bool>(
|
||||
storage_changes
|
||||
.iter()
|
||||
.filter(|changes| inclusion_predicate(&changes.address))
|
||||
.for_each(|storage_change| {
|
||||
.for_each(|&storage_change| {
|
||||
let contract_change = changed_contracts
|
||||
.entry(storage_change.address.clone())
|
||||
.or_insert_with(|| InterimContractChange {
|
||||
address: storage_change.address.clone(),
|
||||
balance: Vec::new(),
|
||||
code: Vec::new(),
|
||||
slots: HashMap::new(),
|
||||
change: if created_accounts.contains_key(&storage_change.address) {
|
||||
tycho::ChangeType::Creation
|
||||
} else {
|
||||
tycho::ChangeType::Update
|
||||
},
|
||||
.or_insert_with(|| {
|
||||
InterimContractChange::new(
|
||||
&storage_change.address,
|
||||
created_accounts.contains_key(&storage_change.address),
|
||||
)
|
||||
});
|
||||
|
||||
let slot_value = contract_change
|
||||
.slots
|
||||
.entry(storage_change.key.clone())
|
||||
.or_insert_with(|| SlotValue {
|
||||
new_value: storage_change.new_value.clone(),
|
||||
start_value: storage_change.old_value.clone(),
|
||||
});
|
||||
.or_insert_with(|| storage_change.into());
|
||||
|
||||
slot_value
|
||||
.new_value
|
||||
@@ -124,16 +139,11 @@ pub fn extract_contract_changes<F: Fn(&[u8]) -> bool>(
|
||||
.for_each(|balance_change| {
|
||||
let contract_change = changed_contracts
|
||||
.entry(balance_change.address.clone())
|
||||
.or_insert_with(|| InterimContractChange {
|
||||
address: balance_change.address.clone(),
|
||||
balance: Vec::new(),
|
||||
code: Vec::new(),
|
||||
slots: HashMap::new(),
|
||||
change: if created_accounts.contains_key(&balance_change.address) {
|
||||
tycho::ChangeType::Creation
|
||||
} else {
|
||||
tycho::ChangeType::Update
|
||||
},
|
||||
.or_insert_with(|| {
|
||||
InterimContractChange::new(
|
||||
&balance_change.address,
|
||||
created_accounts.contains_key(&balance_change.address),
|
||||
)
|
||||
});
|
||||
|
||||
if let Some(new_balance) = &balance_change.new_value {
|
||||
@@ -150,16 +160,11 @@ pub fn extract_contract_changes<F: Fn(&[u8]) -> bool>(
|
||||
.for_each(|code_change| {
|
||||
let contract_change = changed_contracts
|
||||
.entry(code_change.address.clone())
|
||||
.or_insert_with(|| InterimContractChange {
|
||||
address: code_change.address.clone(),
|
||||
balance: Vec::new(),
|
||||
code: Vec::new(),
|
||||
slots: HashMap::new(),
|
||||
change: if created_accounts.contains_key(&code_change.address) {
|
||||
tycho::ChangeType::Creation
|
||||
} else {
|
||||
tycho::ChangeType::Update
|
||||
},
|
||||
.or_insert_with(|| {
|
||||
InterimContractChange::new(
|
||||
&code_change.address,
|
||||
created_accounts.contains_key(&code_change.address),
|
||||
)
|
||||
});
|
||||
|
||||
contract_change.code.clear();
|
||||
@@ -174,17 +179,7 @@ pub fn extract_contract_changes<F: Fn(&[u8]) -> bool>(
|
||||
{
|
||||
transaction_contract_changes
|
||||
.entry(block_tx.index.into())
|
||||
.or_insert_with(|| tycho::TransactionContractChanges {
|
||||
tx: Some(tycho::Transaction {
|
||||
hash: block_tx.hash.clone(),
|
||||
from: block_tx.from.clone(),
|
||||
to: block_tx.to.clone(),
|
||||
index: block_tx.index as u64,
|
||||
}),
|
||||
contract_changes: vec![],
|
||||
component_changes: vec![],
|
||||
balance_changes: vec![],
|
||||
})
|
||||
.or_insert_with(|| tycho::TransactionContractChanges::new(&(block_tx.into())))
|
||||
.contract_changes
|
||||
.extend(
|
||||
changed_contracts
|
||||
|
||||
@@ -3,6 +3,7 @@ pub mod tycho {
|
||||
pub mod evm {
|
||||
// @@protoc_insertion_point(attribute:tycho.evm.v1)
|
||||
pub mod v1 {
|
||||
use substreams_ethereum::pb::eth::v2::{self as sf};
|
||||
include!("tycho.evm.v1.rs");
|
||||
// @@protoc_insertion_point(tycho.evm.v1)
|
||||
|
||||
@@ -16,6 +17,104 @@ pub mod tycho {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&sf::TransactionTrace> for Transaction {
|
||||
fn from(tx: &sf::TransactionTrace) -> Self {
|
||||
Self {
|
||||
hash: tx.hash.clone(),
|
||||
from: tx.from.clone(),
|
||||
to: tx.to.clone(),
|
||||
index: tx.index.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&sf::Block> for Block {
|
||||
fn from(block: &sf::Block) -> Self {
|
||||
Self {
|
||||
number: block.number,
|
||||
hash: block.hash.clone(),
|
||||
parent_hash: block
|
||||
.header
|
||||
.as_ref()
|
||||
.expect("Block header not present")
|
||||
.parent_hash
|
||||
.clone(),
|
||||
ts: block.timestamp_seconds(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ProtocolComponent {
|
||||
pub fn new(id: &str, tx: &Transaction) -> Self {
|
||||
Self {
|
||||
id: id.to_string(),
|
||||
tokens: vec![],
|
||||
contracts: vec![],
|
||||
static_att: vec![],
|
||||
change: ChangeType::Creation.into(),
|
||||
protocol_type: None,
|
||||
tx: Some(tx.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn at_contract(id: &[u8], tx: &Transaction) -> Self {
|
||||
Self {
|
||||
id: format!("0x{}", hex::encode(id)),
|
||||
tokens: vec![],
|
||||
contracts: vec![id.to_vec()],
|
||||
static_att: vec![],
|
||||
change: ChangeType::Creation.into(),
|
||||
protocol_type: None,
|
||||
tx: Some(tx.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_tokens<B: AsRef<[u8]>>(mut self, tokens: &[B]) -> Self {
|
||||
self.tokens = tokens
|
||||
.iter()
|
||||
.map(|e| e.as_ref().to_vec())
|
||||
.collect::<Vec<Vec<u8>>>();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_contracts<B: AsRef<[u8]>>(mut self, contracts: &[B]) -> Self {
|
||||
self.contracts = contracts
|
||||
.iter()
|
||||
.map(|e| e.as_ref().to_vec())
|
||||
.collect::<Vec<Vec<u8>>>();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_attributes<K: AsRef<str>, V: AsRef<[u8]>>(
|
||||
mut self,
|
||||
attributes: &[(K, V)],
|
||||
) -> Self {
|
||||
self.static_att = attributes
|
||||
.iter()
|
||||
.map(|(k, v)| Attribute {
|
||||
name: k.as_ref().to_string(),
|
||||
value: v.as_ref().to_vec(),
|
||||
change: ChangeType::Creation.into(),
|
||||
})
|
||||
.collect::<Vec<Attribute>>();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn as_swap_type(
|
||||
mut self,
|
||||
name: &str,
|
||||
implementation_type: ImplementationType,
|
||||
) -> Self {
|
||||
self.protocol_type = Some(ProtocolType {
|
||||
name: name.to_string(),
|
||||
financial_type: FinancialType::Swap.into(),
|
||||
attribute_schema: vec![],
|
||||
implementation_type: implementation_type.into(),
|
||||
});
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user