pub struct Block {
pub hash: Vec<u8>,
pub number: u64,
pub size: u64,
pub header: Option<BlockHeader>,
pub uncles: Vec<BlockHeader>,
pub transaction_traces: Vec<TransactionTrace>,
pub balance_changes: Vec<BalanceChange>,
pub detail_level: i32,
pub code_changes: Vec<CodeChange>,
pub system_calls: Vec<Call>,
pub ver: i32,
}
Expand description
Block is the representation of the tracing of a block in the Ethereum
blockchain. A block is a collection of [TransactionTrace] that are grouped
together and processed as an atomic unit. Each [TransactionTrace] is composed
of a series of [Call] (a.k.a internal transactions) and there is also at
least one call per transaction a.k.a the root call which essentially has the
same parameters as the transaction itself (e.g. from
, to
, gas
, value
,
etc.).
The exact tracing method used to build the block must be checked against
[DetailLevel] field. There is two levels of details available, BASE
and
EXTENDED
. The BASE
level has been extracted using archive node RPC calls
and will contain only the block header, transaction receipts and event logs.
Refers to the Firehose service provider to know which blocks are offered on
each network.
The EXTENDED
level has been extracted using the Firehose tracer and all
fields are available in this Protobuf.
The Ethereum block model is used across many chains which means that it happen that certain fields are not available in one chain but are available in another. Each field should be documented when necesssary if it’s available on a subset of chains.
One major concept to get about the Block is the concept of ‘ordinal’. The
ordinal is a number that is used to globally order every element of execution
that happened throughout the processing of the block like
[TransactionTracer], [Call], [Log], [BalanceChange], [StateChange], etc.
Element that have a start and end interval, [Transaction] and [Call], will
have two ordinals: begin_ordinal
and end_ordinal
. Element that are
executed as “point in time” [Log], [BalanceChange], [StateChange], etc. will
have only one ordinal named ordinal
. If you take all of the message in the
Block that have an ‘ordinal’ field in an array and you sort each element
against the ordinal
field, you will get the exact order of execution of
each element in the block.
All the ‘ordinal’ fields in a block are globally unique for the given block,
it is not a chain-wide global ordering. Furthermore, caution must be take
with reverted elements due to execution failure. For anything attached to a
[Call] that has a state_reverted
field set to true
, the ordinal
field
is not reliable and should not be used to order the element against other
elements in the block as those element might have 0 as the ordinal. Only
successful calls have a reliable ordinal
field.
Fields§
§hash: Vec<u8>
Hash is the block’s hash.
number: u64
Number is the block’s height at which this block was mined.
size: u64
Size is the size in bytes of the RLP encoding of the block according to Ethereum rules.
header: Option<BlockHeader>
Header contain’s the block’s header information like its parent hash, the merkel root hash and all other information the form a block.
uncles: Vec<BlockHeader>
Uncles represents block produced with a valid solution but were not actually chosen as the canonical block for the given height so they are mostly “forked” blocks.
If the Block has been produced using the Proof of Stake consensus algorithm, this field will actually be always empty.
transaction_traces: Vec<TransactionTrace>
TransactionTraces hold the execute trace of all the transactions that were executed in this block. In in there that you will find most of the Ethereum data model.
They are ordered by the order of execution of the transaction in the block.
balance_changes: Vec<BalanceChange>
BalanceChanges here is the array of ETH transfer that happened at the block level
outside of the normal transaction flow of a block. The best example of this is mining
reward for the block mined, the transfer of ETH to the miner happens outside the normal
transaction flow of the chain and is recorded as a BalanceChange
here since we cannot
attached it to any transaction.
Only available in DetailLevel: EXTENDED
detail_level: i32
DetailLevel affects the data available in this block.
§DetailLevel_EXTENDED
Describes the most complete block, with traces, balance changes, storage changes. It is extracted during the execution of the block.
§DetailLevel_BASE
Describes a block that contains only the block header, transaction receipts and event logs: everything that can be extracted using the base JSON-RPC interface (https://ethereum.org/en/developers/docs/apis/json-rpc/#json-rpc-methods) Furthermore, the eth_getTransactionReceipt call has been avoided because it brings only minimal improvements at the cost of requiring an archive node or a full node with complete transaction index.
code_changes: Vec<CodeChange>
CodeChanges here is the array of smart code change that happened that happened at the block level outside of the normal transaction flow of a block. Some Ethereum’s fork like BSC and Polygon has some capabilities to upgrade internal smart contracts used usually to track the validator list.
On hard fork, some procedure runs to upgrade the smart contract code to a new version. In those
network, a CodeChange
for each modified smart contract on upgrade would be present here. Note
that this happen rarely, so the vast majority of block will have an empty list here.
Only available in DetailLevel: EXTENDED
system_calls: Vec<Call>
System calls are introduced in Cancun, along with blobs. They are executed outside of transactions but affect the state.
Only available in DetailLevel: EXTENDED
ver: i32
Ver represents that data model version of the block, it is used internally by Firehose on Ethereum as a validation that we are reading the correct version.
Implementations§
Source§impl Block
impl Block
Sourcepub fn detail_level(&self) -> DetailLevel
pub fn detail_level(&self) -> DetailLevel
Returns the enum value of detail_level
, or the default if the field is set to an invalid enum value.
Sourcepub fn set_detail_level(&mut self, value: DetailLevel)
pub fn set_detail_level(&mut self, value: DetailLevel)
Sets detail_level
to the provided enum value.
Source§impl Block
impl Block
Sourcepub fn transactions(&self) -> impl Iterator<Item = &TransactionTrace>
pub fn transactions(&self) -> impl Iterator<Item = &TransactionTrace>
Iterates over successful transactions
Sourcepub fn receipts(&self) -> impl Iterator<Item = ReceiptView<'_>>
pub fn receipts(&self) -> impl Iterator<Item = ReceiptView<'_>>
Iterates over transaction receipts of successful transactions.
Sourcepub fn logs(&self) -> impl Iterator<Item = LogView<'_>>
pub fn logs(&self) -> impl Iterator<Item = LogView<'_>>
Iterates over logs in receipts of succesful transactions.
Sourcepub fn calls(&self) -> impl Iterator<Item = CallView<'_>>
pub fn calls(&self) -> impl Iterator<Item = CallView<'_>>
Iterates over calls of successful transactions.
Sourcepub fn events<'a, E>(
&'a self,
addresses: &'a [&[u8]],
) -> impl Iterator<Item = (E, LogView<'a>)>where
E: Event,
pub fn events<'a, E>(
&'a self,
addresses: &'a [&[u8]],
) -> impl Iterator<Item = (E, LogView<'a>)>where
E: Event,
A convenience for handlers that process a single type of event. Returns an iterator over
pairs of (event, log)
.
If you need to process multiple event types in a single handler, try something like:
for log in block.logs() {
if !addresses.contains(&log.address()) {
continue;
}
if let Some(event) = E1::match_and_decode(log) {
// Process events of type E1
} else if let Some(event) = E2::match_and_decode(log) {
// Process events of type E2
}
}
Sourcepub fn timestamp(&self) -> &Timestamp
pub fn timestamp(&self) -> &Timestamp
Timestamp returns a reference to the block’s header timestamp.
Sourcepub fn timestamp_seconds(&self) -> u64
pub fn timestamp_seconds(&self) -> u64
Timestamp returns block’s header timestamp in seconds.
Trait Implementations§
Source§impl Message for Block
impl Message for Block
Source§fn encoded_len(&self) -> usize
fn encoded_len(&self) -> usize
Source§fn encode(&self, buf: &mut impl BufMut) -> Result<(), EncodeError>where
Self: Sized,
fn encode(&self, buf: &mut impl BufMut) -> Result<(), EncodeError>where
Self: Sized,
Source§fn encode_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
fn encode_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
Source§fn encode_length_delimited(
&self,
buf: &mut impl BufMut,
) -> Result<(), EncodeError>where
Self: Sized,
fn encode_length_delimited(
&self,
buf: &mut impl BufMut,
) -> Result<(), EncodeError>where
Self: Sized,
Source§fn encode_length_delimited_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
fn encode_length_delimited_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
Source§fn decode(buf: impl Buf) -> Result<Self, DecodeError>where
Self: Default,
fn decode(buf: impl Buf) -> Result<Self, DecodeError>where
Self: Default,
Source§fn decode_length_delimited(buf: impl Buf) -> Result<Self, DecodeError>where
Self: Default,
fn decode_length_delimited(buf: impl Buf) -> Result<Self, DecodeError>where
Self: Default,
Source§fn merge(&mut self, buf: impl Buf) -> Result<(), DecodeError>where
Self: Sized,
fn merge(&mut self, buf: impl Buf) -> Result<(), DecodeError>where
Self: Sized,
self
. Read moreSource§fn merge_length_delimited(&mut self, buf: impl Buf) -> Result<(), DecodeError>where
Self: Sized,
fn merge_length_delimited(&mut self, buf: impl Buf) -> Result<(), DecodeError>where
Self: Sized,
self
.