Skip to content

Commit edee4b0

Browse files
feat: Add get_block_storage_changes (#203)
* feat: add DCI message definitions #time 4m #time 2m * fix: Make entrypoints into a HashSet instead of Vec #time 0m * fix: Rollback on message index change in ContractSlot #time 5m * feat: Add get_block_storage_changes #time 34m #time 0m * Update substreams/crates/tycho-substreams/src/block_storage.rs Co-authored-by: Louise Poole <louisecarmenpoole@gmail.com> * Update substreams/crates/tycho-substreams/src/block_storage.rs Co-authored-by: Louise Poole <louisecarmenpoole@gmail.com> * fix: Filter out calls that are reverted and sort change by ordinal #time 0m * fix: Improve performance of get_block_storage_changes We expect this util function to collect and handle a lot of information repeatedly (on every single block). So top performance optimisation (both memory and computation) is vital to minimise substream lags. #time 6m * fix: Use filter and flat_map instead of if and for loops #time 1m --------- Co-authored-by: Louise Poole <louise@datarevenue.com> Co-authored-by: Louise Poole <louisecarmenpoole@gmail.com>
1 parent e8bde64 commit edee4b0

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use std::collections::HashMap;
2+
3+
use substreams_ethereum::pb::{
4+
eth,
5+
eth::v2::{block::DetailLevel, StorageChange},
6+
};
7+
8+
use crate::{
9+
models::{ContractSlot, StorageChanges, Transaction},
10+
pb::tycho::evm::v1::TransactionStorageChanges,
11+
};
12+
13+
#[allow(dead_code)]
14+
/// Helper function to extract all storage changes on a block.
15+
/// The raw block information collected is intended to be used by the DCI (Dynamic Contract Indexer)
16+
/// to extract and index relevant changes. This is specifically for dynamically identified contracts
17+
/// that the DCI has chosen to index. Note that core protocol data should still be properly
18+
/// integrated and indexed by the substreams package as per usual.
19+
///
20+
/// ## Panics
21+
/// Panics if the provided block is not an extended block model, as indicated by its detail level.
22+
///
23+
/// ## Warning
24+
/// ⚠️ This function *only* works if the **extended block model** is available,
25+
/// more [here](https://streamingfastio.medium.com/new-block-model-to-accelerate-chain-integration-9f65126e5425)
26+
fn get_block_storage_changes(block: &eth::v2::Block) -> Vec<TransactionStorageChanges> {
27+
if block.detail_level != Into::<i32>::into(DetailLevel::DetaillevelExtended) {
28+
panic!("Only extended blocks are supported");
29+
}
30+
let mut block_storage_changes = Vec::with_capacity(block.transaction_traces.len());
31+
32+
for block_tx in block.transactions() {
33+
let transaction: Transaction = block_tx.into();
34+
35+
let mut changes_by_address: HashMap<Vec<u8>, Vec<StorageChange>> = HashMap::new();
36+
for storage_change in block_tx
37+
.calls
38+
.iter()
39+
.filter(|call| !call.state_reverted)
40+
.flat_map(|call| call.storage_changes.iter())
41+
{
42+
changes_by_address
43+
.entry(storage_change.address.clone())
44+
.or_default()
45+
.push(storage_change.clone());
46+
}
47+
48+
// For each address, sort by ordinal and collect latest changes per slot
49+
let tx_storage_changes: Vec<StorageChanges> = changes_by_address
50+
.into_iter()
51+
.map(|(address, mut changes)| {
52+
changes.sort_unstable_by_key(|change| change.ordinal);
53+
54+
// Collect latest change per slot
55+
let mut latest_changes: HashMap<Vec<u8>, ContractSlot> = HashMap::new();
56+
for change in changes {
57+
latest_changes.insert(
58+
change.key.clone(),
59+
ContractSlot { slot: change.key, value: change.new_value },
60+
);
61+
}
62+
63+
StorageChanges { address, slots: latest_changes.into_values().collect() }
64+
})
65+
.collect();
66+
67+
block_storage_changes.push(TransactionStorageChanges {
68+
tx: Some(transaction),
69+
storage_changes: tx_storage_changes,
70+
});
71+
}
72+
73+
block_storage_changes
74+
}

substreams/crates/tycho-substreams/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub mod abi;
22
pub mod attributes;
33
pub mod balances;
4+
pub mod block_storage;
45
pub mod contract;
56
mod mock_store;
67
pub mod models;

0 commit comments

Comments
 (0)