Skip to content

Commit

Permalink
add creation traces
Browse files Browse the repository at this point in the history
  • Loading branch information
DenisCarriere committed Nov 19, 2024
1 parent a89262b commit c25ae1e
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 11 deletions.
2 changes: 2 additions & 0 deletions blocks/evm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- [x] **Account Creation**
- [x] **Gas Changes**
- [x] **Nonce Changes**
- [x] **Creation Traces**

## Graph

Expand All @@ -34,6 +35,7 @@ graph TD;
extended --> account_creations;
extended --> gas_changes;
extended --> nonce_changes;
extended --> creation_traces;
```

## Modules
Expand Down
12 changes: 12 additions & 0 deletions blocks/evm/src/account_creations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@ pub fn collect_account_creations(block: &Block, timestamp: &BlockTimestamp) -> V
for call in &block.system_calls {
for account_creation in &call.account_creations {
account_creations.push(AccountCreation {
// block
block_time: Some(timestamp.time),
block_number: timestamp.number,
block_hash: timestamp.hash.clone(),
block_date: timestamp.date.clone(),

// transaction
tx_hash: Some("".to_string()),

// account creation
account: bytes_to_hex(&account_creation.account),
ordinal: account_creation.ordinal,
});
Expand All @@ -29,10 +35,16 @@ pub fn collect_account_creations(block: &Block, timestamp: &BlockTimestamp) -> V
for call in &transaction.calls {
for account_creation in &call.account_creations {
account_creations.push(AccountCreation {
// block
block_time: Some(timestamp.time),
block_number: timestamp.number,
block_hash: timestamp.hash.clone(),
block_date: timestamp.date.clone(),

// transaction
tx_hash: Some(bytes_to_hex(&transaction.hash)),

// account creation
account: bytes_to_hex(&account_creation.account),
ordinal: account_creation.ordinal,
});
Expand Down
6 changes: 6 additions & 0 deletions blocks/evm/src/balance_changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@ pub fn collect_balance_changes(block: &Block, timestamp: &BlockTimestamp) -> Vec
for balance_change in &call.balance_changes {
let amount = optional_bigint_to_decimal(balance_change.new_value.clone()) - optional_bigint_to_decimal(balance_change.old_value.clone());
balance_changes.push(BalanceChange {
// block
block_time: Some(timestamp.time),
block_number: timestamp.number,
block_hash: timestamp.hash.clone(),
block_date: timestamp.date.clone(),

// balance changes
address: bytes_to_hex(&balance_change.address),
new_balance: optional_bigint_to_string(&balance_change.new_value, "0"),
old_balance: optional_bigint_to_string(&balance_change.old_value, "0"),
Expand All @@ -64,10 +67,13 @@ pub fn collect_balance_changes(block: &Block, timestamp: &BlockTimestamp) -> Vec
for balance_change in &call.balance_changes {
let amount = optional_bigint_to_decimal(balance_change.new_value.clone()) - optional_bigint_to_decimal(balance_change.old_value.clone());
balance_changes.push(BalanceChange {
// block
block_time: Some(timestamp.time),
block_number: timestamp.number,
block_hash: timestamp.hash.clone(),
block_date: timestamp.date.clone(),

// balance changes
address: bytes_to_hex(&balance_change.address),
new_balance: optional_bigint_to_string(&balance_change.new_value, "0"),
old_balance: optional_bigint_to_string(&balance_change.old_value, "0"),
Expand Down
5 changes: 5 additions & 0 deletions blocks/evm/src/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ pub fn collect_block(block: &Block, timestamp: &BlockTimestamp) -> BlockHeader {
let total_withdrawals = block.balance_changes.iter().filter(|t| t.reason == 16).count() as u64;

BlockHeader {
// clock
time: Some(timestamp.time),
number: header.number,
date: timestamp.date.clone(),
hash: bytes_to_hex(&block.hash),

// header
parent_hash: bytes_to_hex(&header.parent_hash),
nonce: header.nonce,
ommers_hash: bytes_to_hex(&header.uncle_hash),
Expand All @@ -50,6 +53,8 @@ pub fn collect_block(block: &Block, timestamp: &BlockTimestamp) -> BlockHeader {
base_fee_per_gas: optional_bigint_to_string(&header.base_fee_per_gas, ""),
blob_gas_used: optional_u64_to_string(&header.blob_gas_used, ""),
excess_blob_gas: optional_u64_to_string(&header.excess_blob_gas, ""),

// counters
size: block.size,
total_transactions: block.transaction_traces.len() as u64,
successful_transactions,
Expand Down
6 changes: 6 additions & 0 deletions blocks/evm/src/code_changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ pub fn collect_code_changes(block: &Block, timestamp: &BlockTimestamp) -> Vec<Co
for call in &block.system_calls {
for code_change in &call.code_changes {
code_changes.push(CodeChange {
// block
block_time: Some(timestamp.time),
block_number: timestamp.number,
block_hash: timestamp.hash.clone(),
block_date: timestamp.date.clone(),

// code changes
address: bytes_to_hex(&code_change.address),
old_hash: bytes_to_hex(&code_change.old_hash),
old_code: bytes_to_hex(&code_change.old_code),
Expand All @@ -32,10 +35,13 @@ pub fn collect_code_changes(block: &Block, timestamp: &BlockTimestamp) -> Vec<Co
for call in &transaction.calls {
for code_change in &call.code_changes {
code_changes.push(CodeChange {
// block
block_time: Some(timestamp.time),
block_number: timestamp.number,
block_hash: timestamp.hash.clone(),
block_date: timestamp.date.clone(),

// code changes
address: bytes_to_hex(&code_change.address),
old_hash: bytes_to_hex(&code_change.old_hash),
old_code: bytes_to_hex(&code_change.old_code),
Expand Down
39 changes: 39 additions & 0 deletions blocks/evm/src/creation_traces.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use common::structs::BlockTimestamp;
use common::utils::bytes_to_hex;
use substreams_ethereum::pb::eth::v2::{Block, CallType};

use crate::pb::evm::CreationTrace;

// https://github.com/streamingfast/firehose-ethereum/blob/1bcb32a8eb3e43347972b6b5c9b1fcc4a08c751e/proto/sf/ethereum/type/v2/type.proto#L744
// DetailLevel: EXTENDED
pub fn collect_creation_traces(block: &Block, timestamp: &BlockTimestamp) -> Vec<CreationTrace> {
let mut creation_traces: Vec<CreationTrace> = vec![];

// Collect code changes from system calls
for trace in block.transaction_traces.iter() {
for call in trace.calls.iter() {
if call.call_type() == CallType::Create {
for code in call.code_changes.iter() {
let factory = if trace.to == code.address { "".to_string() } else { bytes_to_hex(&trace.to) };

creation_traces.push(CreationTrace {
// block
block_time: Some(timestamp.time),
block_number: timestamp.number,
block_hash: timestamp.hash.clone(),
block_date: timestamp.date.clone(),

// creation trace
from: bytes_to_hex(&trace.from),
tx_hash: bytes_to_hex(&trace.hash),
address: bytes_to_hex(&code.address),
factory: factory.to_string(),
code: bytes_to_hex(&code.new_code),
});
}
}
}
}

creation_traces
}
2 changes: 2 additions & 0 deletions blocks/evm/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::account_creations::collect_account_creations;
use crate::balance_changes::collect_balance_changes;
use crate::blocks::{block_detail_to_string, collect_block};
use crate::code_changes::collect_code_changes;
use crate::creation_traces::collect_creation_traces;
use crate::gas_changes::collect_gas_changes;
use crate::logs::collect_logs;
use crate::nonce_changes::collect_nonce_changes;
Expand All @@ -32,5 +33,6 @@ pub fn map_events(clock: Clock, block: Block) -> Result<Events, Error> {
account_creations: collect_account_creations(&block, &timestamp),
nonce_changes: collect_nonce_changes(&block, &timestamp),
gas_changes: collect_gas_changes(&block, &timestamp),
creation_traces: collect_creation_traces(&block, &timestamp),
})
}
1 change: 1 addition & 0 deletions blocks/evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod account_creations;
mod balance_changes;
mod blocks;
mod code_changes;
mod creation_traces;
mod events;
mod gas_changes;
mod logs;
Expand Down
6 changes: 3 additions & 3 deletions blocks/evm/src/logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ pub fn collect_logs(block: &Block, timestamp: &BlockTimestamp, detail_level: &st
block_index: log.block_index,
contract_address: bytes_to_hex(&log.address),
topic0: extract_topic(&log.topics, 0),
topic1: extract_topic(&log.topics, 1),
topic2: extract_topic(&log.topics, 2),
topic3: extract_topic(&log.topics, 3),
topic1: Some(extract_topic(&log.topics, 1)),
topic2: Some(extract_topic(&log.topics, 2)),
topic3: Some(extract_topic(&log.topics, 3)),
data: bytes_to_hex(&log.data),
});
}
Expand Down
33 changes: 30 additions & 3 deletions blocks/evm/src/pb/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub struct Events {
pub nonce_changes: ::prost::alloc::vec::Vec<NonceChange>,
#[prost(message, repeated, tag="10")]
pub gas_changes: ::prost::alloc::vec::Vec<GasChange>,
#[prost(message, repeated, tag="11")]
pub creation_traces: ::prost::alloc::vec::Vec<CreationTrace>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
Expand Down Expand Up @@ -389,11 +391,12 @@ pub struct AccountCreation {
#[prost(string, tag="4")]
pub block_date: ::prost::alloc::string::String,
/// -- account creation --
///
#[prost(string, optional, tag="5")]
pub tx_hash: ::core::option::Option<::prost::alloc::string::String>,
/// block global ordinal
#[prost(uint64, tag="5")]
#[prost(uint64, tag="6")]
pub ordinal: u64,
#[prost(string, tag="6")]
#[prost(string, tag="7")]
pub account: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
Expand Down Expand Up @@ -446,4 +449,28 @@ pub struct GasChange {
#[prost(uint32, tag="9")]
pub reason_code: u32,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct CreationTrace {
/// -- block --
#[prost(message, optional, tag="1")]
pub block_time: ::core::option::Option<::prost_types::Timestamp>,
#[prost(uint64, tag="2")]
pub block_number: u64,
#[prost(string, tag="3")]
pub block_hash: ::prost::alloc::string::String,
#[prost(string, tag="4")]
pub block_date: ::prost::alloc::string::String,
/// -- creation trace --
#[prost(string, tag="5")]
pub tx_hash: ::prost::alloc::string::String,
#[prost(string, tag="6")]
pub address: ::prost::alloc::string::String,
#[prost(string, tag="7")]
pub from: ::prost::alloc::string::String,
#[prost(string, tag="8")]
pub factory: ::prost::alloc::string::String,
#[prost(string, tag="9")]
pub code: ::prost::alloc::string::String,
}
// @@protoc_insertion_point(module)
5 changes: 5 additions & 0 deletions docs/google_big_query.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Google Big Query

<https://cloud.google.com/blockchain-analytics/docs/example-ethereum>

<https://console.cloud.google.com/marketplace/details/ethereum/crypto-ethereum-blockchain?inv=1&invt=Abh5Fw&organizationId=628547290088>
30 changes: 25 additions & 5 deletions proto/evm.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ message Events {
repeated AccountCreation account_creations = 8;
repeated NonceChange nonce_changes = 9;
repeated GasChange gas_changes = 10;
repeated CreationTrace creation_traces = 11;
}


message Block {
// -- clock --
google.protobuf.Timestamp time = 1;
Expand All @@ -37,8 +37,8 @@ message Block {
string withdrawals_root = 12; // EVM Root EIP-4895 (Shangai Fork)
string parent_beacon_root = 13; // EVM Root EIP-4788 (Dencun Fork)
string miner = 14;
uint64 difficulty = 15 [(parquet.column) = {type: UINT256}];
string total_difficulty = 16;
uint64 difficulty = 15;
string total_difficulty = 16 [(parquet.column) = {type: UINT256}];
string mix_hash = 17;
string extra_data = 18;
string extra_data_utf8 = 19;
Expand Down Expand Up @@ -226,9 +226,12 @@ message AccountCreation {
string block_hash = 3;
string block_date = 4;

// -- transaction --
optional string tx_hash = 5;

// -- account creation --
uint64 ordinal = 5; // block global ordinal
string account = 6;
uint64 ordinal = 6; // block global ordinal
string account = 7;
}

message NonceChange {
Expand Down Expand Up @@ -259,3 +262,20 @@ message GasChange {
string reason = 8;
uint32 reason_code = 9;
}

message CreationTrace {
// -- block --
google.protobuf.Timestamp block_time = 1;
uint64 block_number = 2;
string block_hash = 3;
string block_date = 4;

// -- transaction --
string tx_hash = 5;

// -- creation trace --
string address = 6;
string from = 7;
string factory = 8;
string code = 9;
}
1 change: 1 addition & 0 deletions snowflake/ethereum/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Try 30 day limited trial access to the dataset on the [Snowflake Data Marketplac
| `logs` | Event logs from smart contracts. |
| `storage_changes` | Changes in smart contract storage. |
| `code_changes` | Smart contract code updates. |
| `creation_traces` | Contract creation transactions. |

## Sample SQL Queries

Expand Down

0 comments on commit c25ae1e

Please sign in to comment.