Skip to content

Commit

Permalink
refactor: implement AccessTuple conversion methods in firehose-protos
Browse files Browse the repository at this point in the history
  • Loading branch information
suchapalaver committed Oct 25, 2024
1 parent 4450967 commit 8c97ebe
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 26 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/firehose-protos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ doctest = false
path = "src/lib.rs"

[dependencies]
alloy-eip2930.workspace = true
alloy-primitives.workspace = true
ethportal-api.workspace = true
primitive-types.workspace = true
Expand Down
3 changes: 3 additions & 0 deletions crates/firehose-protos/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ pub enum ProtosError {
#[error("GraffitiInvalid")]
GraffitiInvalid,

#[error("Invalid access tuple storage key: {0}")]
InvalidAccessTupleStorageKey(String),

#[error("Invalid log address: {0}")]
InvalidLogAddress(String),

Expand Down
86 changes: 86 additions & 0 deletions crates/firehose-protos/src/ethereum_v2/access.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use crate::error::ProtosError;

use super::AccessTuple;

use alloy_eip2930::AccessListItem;
use alloy_primitives::{hex, Address, B256};

impl TryFrom<&AccessTuple> for AccessListItem {
type Error = ProtosError;

fn try_from(tuple: &AccessTuple) -> Result<Self, Self::Error> {
let address = Address::from_slice(tuple.address.as_slice());

let storage_keys = tuple
.storage_keys
.iter()
.map(convert_to_b256)
.collect::<Result<Vec<B256>, ProtosError>>()?;

Ok(AccessListItem {
address,
storage_keys,
})
}
}

fn convert_to_b256(key: &Vec<u8>) -> Result<B256, ProtosError> {
let key_bytes: [u8; 32] = key
.as_slice()
.try_into()
.map_err(|_| ProtosError::InvalidAccessTupleStorageKey(hex::encode(key.clone())))?;
Ok(B256::from(key_bytes))
}

#[cfg(test)]
mod tests {
use super::*;

fn create_mock_access_tuple() -> AccessTuple {
AccessTuple {
address: vec![0x11; 20],
storage_keys: vec![vec![0xaa; 32], vec![0xbb; 32]],
}
}

#[test]
fn test_access_tuple_to_access_list_item_conversion() {
let mock_tuple = create_mock_access_tuple();

let access_list_item = AccessListItem::try_from(&mock_tuple).expect("Conversion failed");

assert_eq!(access_list_item.address, Address::from([0x11; 20]));
assert_eq!(
access_list_item.storage_keys.len(),
mock_tuple.storage_keys.len()
);
}

#[test]
fn test_access_tuple_with_empty_storage_keys() {
let mock_tuple = AccessTuple {
address: vec![0x11; 20],
storage_keys: vec![],
};

let access_list_item = AccessListItem::try_from(&mock_tuple).expect("Conversion failed");

assert_eq!(access_list_item.address, Address::from([0x11; 20]));
assert!(access_list_item.storage_keys.is_empty());
}

#[test]
fn test_access_tuple_storage_key_invalid_length() {
let mock_tuple = AccessTuple {
address: vec![0x11; 20],
storage_keys: vec![vec![0xaa; 31]],
};

let error = AccessListItem::try_from(&mock_tuple).unwrap_err();

assert!(matches!(
error,
ProtosError::InvalidAccessTupleStorageKey(_)
));
}
}
1 change: 1 addition & 0 deletions crates/firehose-protos/src/ethereum_v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! See the protobuffer definitions section of the README for more information.
//!

pub mod access;
pub mod eth_block;
pub mod log;
pub mod transaction;
Expand Down
29 changes: 3 additions & 26 deletions crates/flat-files-decoder/src/transactions/access_list.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,14 @@
use crate::transactions::error::TransactionError;
use alloy_eip2930::{AccessList, AccessListItem};
use alloy_primitives::{Address, B256};
use firehose_protos::ethereum_v2::AccessTuple;
use revm_primitives::hex;

pub(crate) fn compute_access_list(
access_list: &[AccessTuple],
) -> Result<AccessList, TransactionError> {
let access_list_items: Vec<AccessListItem> = access_list
let access_list_items = access_list
.iter()
.map(atuple_to_alist_item)
.collect::<Result<Vec<AccessListItem>, TransactionError>>(
)?;
.map(AccessListItem::try_from)
.collect::<Result<Vec<AccessListItem>, _>>()?;

Ok(AccessList(access_list_items))
}

fn atuple_to_alist_item(tuple: &AccessTuple) -> Result<AccessListItem, TransactionError> {
let address: Address = Address::from_slice(tuple.address.as_slice());
let storage_keys = tuple
.storage_keys
.iter()
.map(|key| {
let key_bytes: [u8; 32] = key
.as_slice()
.try_into()
.map_err(|_| TransactionError::InvalidStorageKey(hex::encode(key.clone())))?;
Ok(B256::from(key_bytes))
})
.collect::<Result<Vec<B256>, TransactionError>>()?;

Ok(AccessListItem {
address,
storage_keys,
})
}
3 changes: 3 additions & 0 deletions crates/flat-files-decoder/src/transactions/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::transactions::signature::InvalidSignatureError;
use crate::transactions::tx_type::TransactionTypeError;
use firehose_protos::error::ProtosError;
use thiserror::Error;

#[derive(Error, Debug)]
Expand All @@ -26,4 +27,6 @@ pub enum TransactionError {
MissingMaxFeePerGas,
#[error("Missing Header")]
MissingHeader,
#[error("Protos Error: {0}")]
ProtosError(#[from] ProtosError),
}

0 comments on commit 8c97ebe

Please sign in to comment.