feat(examples): remove Remote ExEx (#9085)

This commit is contained in:
Alexey Shekhirin
2024-06-25 12:21:01 +01:00
committed by GitHub
parent 23d8e4e6f6
commit 6699c6a3d7
12 changed files with 19 additions and 1694 deletions

View File

@ -41,7 +41,7 @@ jobs:
run: |
cargo nextest run \
--locked --features "asm-keccak ${{ matrix.network }}" \
--workspace --exclude example-exex-remote --exclude ef-tests \
--workspace --exclude ef-tests \
-E "kind(test)"
- if: matrix.network == 'optimism'
name: Run tests

View File

@ -41,9 +41,6 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- run: cargo clippy --workspace --lib --examples --tests --benches --all-features --locked
env:
RUSTFLAGS: -D warnings
@ -73,7 +70,6 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- uses: arduino/setup-protoc@v3
- run: cargo hack check
msrv:
@ -109,7 +105,6 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- uses: arduino/setup-protoc@v3
- run: cargo docs --document-private-items
env:
# Keep in sync with ./book.yml:jobs.build

View File

@ -39,7 +39,7 @@ jobs:
run: |
cargo nextest run \
--locked --features "asm-keccak ${{ matrix.network }}" \
--workspace --exclude example-exex-remote --exclude ef-tests \
--workspace --exclude ef-tests \
--partition hash:${{ matrix.partition }}/2 \
-E "!kind(test)"
@ -84,9 +84,6 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Run doctests
run: cargo test --doc --workspace --features "${{ matrix.network }}"

301
Cargo.lock generated
View File

@ -1064,51 +1064,6 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "axum"
version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
dependencies = [
"async-trait",
"axum-core",
"bitflags 1.3.2",
"bytes",
"futures-util",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.29",
"itoa",
"matchit",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"rustversion",
"serde",
"sync_wrapper 0.1.2",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "axum-core"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
dependencies = [
"async-trait",
"bytes",
"futures-util",
"http 0.2.12",
"http-body 0.4.6",
"mime",
"rustversion",
"tower-layer",
"tower-service",
]
[[package]]
name = "backon"
version = "0.4.4"
@ -2921,25 +2876,6 @@ dependencies = [
"tokio",
]
[[package]]
name = "example-exex-remote"
version = "0.0.0"
dependencies = [
"bincode",
"eyre",
"prost",
"reth",
"reth-exex",
"reth-exex-test-utils",
"reth-node-api",
"reth-node-ethereum",
"reth-tracing",
"tokio",
"tokio-stream",
"tonic",
"tonic-build",
]
[[package]]
name = "example-exex-rollup"
version = "0.0.0"
@ -3193,12 +3129,6 @@ dependencies = [
"static_assertions",
]
[[package]]
name = "fixedbitset"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flate2"
version = "1.0.30"
@ -3487,25 +3417,6 @@ dependencies = [
"subtle",
]
[[package]]
name = "h2"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http 0.2.12",
"indexmap 2.2.6",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "h2"
version = "0.4.5"
@ -3706,17 +3617,6 @@ dependencies = [
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes",
"http 0.2.12",
"pin-project-lite",
]
[[package]]
name = "http-body"
version = "1.0.0"
@ -3736,7 +3636,7 @@ dependencies = [
"bytes",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"http-body",
"pin-project-lite",
]
@ -3800,30 +3700,6 @@ dependencies = [
"serde",
]
[[package]]
name = "hyper"
version = "0.14.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2 0.3.26",
"http 0.2.12",
"http-body 0.4.6",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"socket2 0.5.7",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]]
name = "hyper"
version = "1.3.1"
@ -3833,9 +3709,9 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
"h2 0.4.5",
"h2",
"http 1.1.0",
"http-body 1.0.0",
"http-body",
"httparse",
"httpdate",
"itoa",
@ -3853,7 +3729,7 @@ checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155"
dependencies = [
"futures-util",
"http 1.1.0",
"hyper 1.3.1",
"hyper",
"hyper-util",
"log",
"rustls",
@ -3865,18 +3741,6 @@ dependencies = [
"webpki-roots",
]
[[package]]
name = "hyper-timeout"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
dependencies = [
"hyper 0.14.29",
"pin-project-lite",
"tokio",
"tokio-io-timeout",
]
[[package]]
name = "hyper-util"
version = "0.1.5"
@ -3887,8 +3751,8 @@ dependencies = [
"futures-channel",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"hyper 1.3.1",
"http-body",
"hyper",
"pin-project-lite",
"socket2 0.5.7",
"tokio",
@ -4423,7 +4287,7 @@ dependencies = [
"futures-timer",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"http-body",
"http-body-util",
"jsonrpsee-types",
"parking_lot 0.12.3",
@ -4447,8 +4311,8 @@ checksum = "fb25cab482c8512c4f3323a5c90b95a3b8f7c90681a87bf7a68b942d52f08933"
dependencies = [
"async-trait",
"base64 0.22.1",
"http-body 1.0.0",
"hyper 1.3.1",
"http-body",
"hyper",
"hyper-rustls",
"hyper-util",
"jsonrpsee-core",
@ -4486,9 +4350,9 @@ dependencies = [
"anyhow",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"http-body",
"http-body-util",
"hyper 1.3.1",
"hyper",
"hyper-util",
"jsonrpsee-core",
"jsonrpsee-types",
@ -4915,12 +4779,6 @@ dependencies = [
"regex-automata 0.1.10",
]
[[package]]
name = "matchit"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "memchr"
version = "2.7.4"
@ -5160,12 +5018,6 @@ dependencies = [
"unsigned-varint 0.7.2",
]
[[package]]
name = "multimap"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
[[package]]
name = "multistream-select"
version = "0.13.0"
@ -5574,16 +5426,6 @@ dependencies = [
"ucd-trie",
]
[[package]]
name = "petgraph"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
dependencies = [
"fixedbitset",
"indexmap 2.2.6",
]
[[package]]
name = "ph"
version = "0.8.3"
@ -5970,59 +5812,6 @@ dependencies = [
"syn 2.0.67",
]
[[package]]
name = "prost"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29"
dependencies = [
"bytes",
"prost-derive",
]
[[package]]
name = "prost-build"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4"
dependencies = [
"bytes",
"heck 0.5.0",
"itertools 0.12.1",
"log",
"multimap",
"once_cell",
"petgraph",
"prettyplease",
"prost",
"prost-types",
"regex",
"syn 2.0.67",
"tempfile",
]
[[package]]
name = "prost-derive"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1"
dependencies = [
"anyhow",
"itertools 0.12.1",
"proc-macro2",
"quote",
"syn 2.0.67",
]
[[package]]
name = "prost-types"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0"
dependencies = [
"prost",
]
[[package]]
name = "quanta"
version = "0.12.3"
@ -6363,9 +6152,9 @@ dependencies = [
"futures-core",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"http-body",
"http-body-util",
"hyper 1.3.1",
"hyper",
"hyper-rustls",
"hyper-util",
"ipnet",
@ -6383,7 +6172,7 @@ dependencies = [
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper 1.0.1",
"sync_wrapper",
"tokio",
"tokio-rustls",
"tokio-util",
@ -8098,8 +7887,8 @@ dependencies = [
"dyn-clone",
"futures",
"http 1.1.0",
"http-body 1.0.0",
"hyper 1.3.1",
"http-body",
"hyper",
"jsonrpsee",
"jsonwebtoken",
"metrics",
@ -9697,12 +9486,6 @@ dependencies = [
"syn 2.0.67",
]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "sync_wrapper"
version = "1.0.1"
@ -10011,16 +9794,6 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "tokio-io-timeout"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
dependencies = [
"pin-project-lite",
"tokio",
]
[[package]]
name = "tokio-macros"
version = "2.3.0"
@ -10131,46 +9904,6 @@ dependencies = [
"winnow 0.6.13",
]
[[package]]
name = "tonic"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13"
dependencies = [
"async-stream",
"async-trait",
"axum",
"base64 0.21.7",
"bytes",
"h2 0.3.26",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.29",
"hyper-timeout",
"percent-encoding",
"pin-project",
"prost",
"tokio",
"tokio-stream",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tonic-build"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4ef6dd70a610078cb4e338a0f79d06bc759ff1b22d2120c2ff02ae264ba9c2"
dependencies = [
"prettyplease",
"proc-macro2",
"prost-build",
"quote",
"syn 2.0.67",
]
[[package]]
name = "tower"
version = "0.4.13"
@ -10205,7 +9938,7 @@ dependencies = [
"futures-core",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"http-body",
"http-body-util",
"http-range-header",
"httpdate",

View File

@ -29,7 +29,6 @@ to make a PR!
| [In Memory State](./exex/in-memory-state) | Illustrates an ExEx that tracks the plain state in memory |
| [Minimal](./exex/minimal) | Illustrates how to build a simple ExEx |
| [OP Bridge](./exex/op-bridge) | Illustrates an ExEx that decodes Optimism deposit and withdrawal receipts from L1 |
| [Remote](./exex/remote) | Illustrates an ExEx that emits notifications using a gRPC server, and a consumer that receives them |
| [Rollup](./exex/rollup) | Illustrates a rollup ExEx that derives the state from L1 |
## RPC

View File

@ -1,42 +0,0 @@
[package]
name = "example-exex-remote"
version = "0.0.0"
publish = false
edition.workspace = true
license.workspace = true
[dependencies]
reth.workspace = true
reth-exex = { workspace = true, features = ["serde"] }
reth-node-api.workspace = true
reth-node-ethereum.workspace = true
reth-tracing.workspace = true
eyre.workspace = true
tonic = "0.11"
prost = "0.12"
tokio = { version = "1.0", features = ["full"] }
tokio-stream = "0.1"
bincode = "1.3"
[build-dependencies]
tonic-build = "0.11"
[dev-dependencies]
reth-exex-test-utils.workspace = true
tokio.workspace = true
[features]
default = []
optimism = ["reth/optimism"]
[[bin]]
name = "exex"
path = "bin/exex.rs"
[[bin]]
name = "consumer"
path = "bin/consumer.rs"

View File

@ -1,32 +0,0 @@
use example_exex_remote::proto::{remote_ex_ex_client::RemoteExExClient, SubscribeRequest};
use reth_exex::ExExNotification;
use reth_tracing::{tracing::info, RethTracer, Tracer};
#[tokio::main]
async fn main() -> eyre::Result<()> {
let _ = RethTracer::new().init()?;
let mut client = RemoteExExClient::connect("http://[::1]:10000")
.await?
.max_encoding_message_size(usize::MAX)
.max_decoding_message_size(usize::MAX);
let mut stream = client.subscribe(SubscribeRequest {}).await?.into_inner();
while let Some(notification) = stream.message().await? {
let notification = ExExNotification::try_from(&notification)?;
match notification {
ExExNotification::ChainCommitted { new } => {
info!(committed_chain = ?new.range(), "Received commit");
}
ExExNotification::ChainReorged { old, new } => {
info!(from_chain = ?old.range(), to_chain = ?new.range(), "Received reorg");
}
ExExNotification::ChainReverted { old } => {
info!(reverted_chain = ?old.range(), "Received revert");
}
};
}
Ok(())
}

View File

@ -1,77 +0,0 @@
use example_exex_remote::proto::{
remote_ex_ex_server::{RemoteExEx, RemoteExExServer},
ExExNotification as ProtoExExNotification, SubscribeRequest as ProtoSubscribeRequest,
};
use reth_exex::{ExExContext, ExExEvent, ExExNotification};
use reth_node_api::FullNodeComponents;
use reth_node_ethereum::EthereumNode;
use tokio::sync::{broadcast, mpsc};
use tokio_stream::wrappers::ReceiverStream;
use tonic::{transport::Server, Request, Response, Status};
#[derive(Debug)]
struct ExExService {
notifications: broadcast::Sender<ExExNotification>,
}
#[tonic::async_trait]
impl RemoteExEx for ExExService {
type SubscribeStream = ReceiverStream<Result<ProtoExExNotification, Status>>;
async fn subscribe(
&self,
_request: Request<ProtoSubscribeRequest>,
) -> Result<Response<Self::SubscribeStream>, Status> {
let (tx, rx) = mpsc::channel(1);
let mut notifications = self.notifications.subscribe();
tokio::spawn(async move {
while let Ok(notification) = notifications.recv().await {
tx.send(Ok((&notification).try_into().expect("failed to encode")))
.await
.expect("failed to send notification to client");
}
});
Ok(Response::new(ReceiverStream::new(rx)))
}
}
async fn exex<Node: FullNodeComponents>(
mut ctx: ExExContext<Node>,
notifications: broadcast::Sender<ExExNotification>,
) -> eyre::Result<()> {
while let Some(notification) = ctx.notifications.recv().await {
if let Some(committed_chain) = notification.committed_chain() {
ctx.events.send(ExExEvent::FinishedHeight(committed_chain.tip().number))?;
}
let _ = notifications.send(notification);
}
Ok(())
}
fn main() -> eyre::Result<()> {
reth::cli::Cli::parse_args().run(|builder, _| async move {
let notifications = broadcast::channel(1).0;
let server = Server::builder()
.add_service(RemoteExExServer::new(ExExService {
notifications: notifications.clone(),
}))
.serve("[::1]:10000".parse().unwrap());
let handle = builder
.node(EthereumNode::default())
.install_exex("Remote", |ctx| async move { Ok(exex(ctx, notifications)) })
.launch()
.await?;
handle.node.task_executor.spawn_critical("gRPC server", async move {
server.await.expect("gRPC server crashed")
});
handle.wait_for_node_exit().await
})
}

View File

@ -1,4 +0,0 @@
fn main() {
tonic_build::compile_protos("proto/exex.proto")
.unwrap_or_else(|e| panic!("Failed to compile protos {:?}", e));
}

View File

@ -1,279 +0,0 @@
syntax = "proto3";
package exex;
import "google/protobuf/empty.proto";
service RemoteExEx {
rpc Subscribe(SubscribeRequest) returns (stream ExExNotification) {}
}
message SubscribeRequest {}
message ExExNotification {
oneof notification {
ChainCommitted chain_committed = 1;
ChainReorged chain_reorged = 2;
ChainReverted chain_reverted = 3;
}
}
message ChainCommitted {
Chain new = 1;
}
message ChainReorged {
Chain old = 1;
Chain new = 2;
}
message ChainReverted {
Chain old = 1;
}
message Chain {
repeated Block blocks = 1;
ExecutionOutcome execution_outcome = 2;
}
message Block {
SealedHeader header = 1;
repeated Transaction body = 2;
repeated Header ommers = 3;
repeated bytes senders = 4;
// TODO: add withdrawals and requests
}
message SealedHeader {
bytes hash = 1;
Header header = 2;
}
message Header {
bytes parent_hash = 1;
bytes ommers_hash = 2;
bytes beneficiary = 3;
bytes state_root = 4;
bytes transactions_root = 5;
bytes receipts_root = 6;
optional bytes withdrawals_root = 7;
bytes logs_bloom = 8;
bytes difficulty = 9;
uint64 number = 10;
uint64 gas_limit = 11;
uint64 gas_used = 12;
uint64 timestamp = 13;
bytes mix_hash = 14;
uint64 nonce = 15;
optional uint64 base_fee_per_gas = 16;
optional uint64 blob_gas_used = 17;
optional uint64 excess_blob_gas = 18;
optional bytes parent_beacon_block_root = 19;
// TODO: add requests_root
bytes extra_data = 20;
}
message Transaction {
bytes hash = 1;
Signature signature = 2;
oneof transaction {
TransactionLegacy legacy = 3;
TransactionEip2930 eip2930 = 4;
TransactionEip1559 eip1559 = 5;
TransactionEip4844 eip4844 = 6;
}
}
message Signature {
bytes r = 1;
bytes s = 2;
bool odd_y_parity = 3;
}
message TransactionLegacy {
optional uint64 chain_id = 1;
uint64 nonce = 2;
bytes gas_price = 3;
uint64 gas_limit = 4;
TxKind to = 5;
bytes value = 6;
bytes input = 7;
}
message TransactionEip2930 {
uint64 chain_id = 1;
uint64 nonce = 2;
bytes gas_price = 3;
uint64 gas_limit = 4;
TxKind to = 5;
bytes value = 6;
repeated AccessListItem access_list = 7;
bytes input = 8;
}
message TransactionEip1559 {
uint64 chain_id = 1;
uint64 nonce = 2;
uint64 gas_limit = 3;
bytes max_fee_per_gas = 4;
bytes max_priority_fee_per_gas = 5;
TxKind to = 6;
bytes value = 7;
repeated AccessListItem access_list = 8;
bytes input = 9;
}
message TransactionEip4844 {
uint64 chain_id = 1;
uint64 nonce = 2;
uint64 gas_limit = 3;
bytes max_fee_per_gas = 4;
bytes max_priority_fee_per_gas = 5;
bytes to = 6;
bytes value = 7;
repeated AccessListItem access_list = 8;
repeated bytes blob_versioned_hashes = 9;
bytes max_fee_per_blob_gas = 10;
bytes input = 11;
}
message TxKind {
oneof kind {
google.protobuf.Empty create = 1;
bytes call = 2;
}
}
message AccessListItem {
bytes address = 1;
repeated bytes storage_keys = 2;
}
message ExecutionOutcome {
BundleState bundle = 1;
repeated BlockReceipts receipts = 2;
uint64 first_block = 3;
// TODO: add requests
}
message BundleState {
repeated BundleAccount state = 1;
repeated ContractBytecode contracts = 2;
repeated BlockReverts reverts = 3;
uint64 state_size = 4;
uint64 reverts_size = 5;
}
message BundleAccount {
bytes address = 1;
AccountInfo info = 2;
AccountInfo original_info = 3;
repeated StorageSlot storage = 4;
AccountStatus status = 5;
}
message AccountInfo {
bytes balance = 1;
uint64 nonce = 2;
bytes code_hash = 3;
Bytecode code = 4;
}
message StorageSlot {
bytes key = 1;
bytes previous_or_original_value = 2;
bytes present_value = 3;
}
enum AccountStatus {
LOADED_NOT_EXISTING = 0;
LOADED = 1;
LOADED_EMPTY_EIP161 = 2;
IN_MEMORY_CHANGE = 3;
CHANGED = 4;
DESTROYED = 5;
DESTROYED_CHANGED = 6;
DESTROYED_AGAIN = 7;
}
message ContractBytecode {
bytes hash = 1;
Bytecode bytecode = 2;
}
message Bytecode {
oneof bytecode {
bytes legacy_raw = 1;
LegacyAnalyzedBytecode legacy_analyzed = 2;
// TODO: add EOF
}
}
message LegacyAnalyzedBytecode {
bytes bytecode = 1;
uint64 original_len = 2;
repeated uint32 jump_table = 3;
}
message BlockReverts {
repeated Revert reverts = 1;
}
message Revert {
bytes address = 1;
AccountInfoRevert account = 2;
repeated RevertToSlot storage = 3;
AccountStatus previous_status = 4;
bool wipe_storage = 5;
}
message AccountInfoRevert {
oneof revert {
google.protobuf.Empty do_nothing = 1;
google.protobuf.Empty delete_it = 2;
AccountInfo revert_to = 3;
}
}
message RevertToSlot {
bytes key = 1;
oneof revert {
bytes some = 2;
google.protobuf.Empty destroyed = 3;
}
}
message BlockReceipts {
repeated Receipt receipts = 1;
}
message Receipt {
oneof receipt {
google.protobuf.Empty empty = 1;
NonEmptyReceipt non_empty = 2;
}
}
message NonEmptyReceipt {
TxType tx_type = 1;
bool success = 2;
uint64 cumulative_gas_used = 3;
repeated Log logs = 4;
}
enum TxType {
LEGACY = 0;
EIP2930 = 1;
EIP1559 = 2;
EIP4844 = 3;
}
message Log {
bytes address = 1;
LogData data = 2;
}
message LogData {
repeated bytes topics = 1;
bytes data = 2;
}

View File

@ -1,961 +0,0 @@
use std::sync::Arc;
use eyre::OptionExt;
use reth::primitives::{Address, BlockHash, Bloom, TxHash, B256, U256};
use crate::proto;
impl TryFrom<&reth_exex::ExExNotification> for proto::ExExNotification {
type Error = eyre::Error;
fn try_from(notification: &reth_exex::ExExNotification) -> Result<Self, Self::Error> {
let notification = match notification {
reth_exex::ExExNotification::ChainCommitted { new } => {
proto::ex_ex_notification::Notification::ChainCommitted(proto::ChainCommitted {
new: Some(new.as_ref().try_into()?),
})
}
reth_exex::ExExNotification::ChainReorged { old, new } => {
proto::ex_ex_notification::Notification::ChainReorged(proto::ChainReorged {
old: Some(old.as_ref().try_into()?),
new: Some(new.as_ref().try_into()?),
})
}
reth_exex::ExExNotification::ChainReverted { old } => {
proto::ex_ex_notification::Notification::ChainReverted(proto::ChainReverted {
old: Some(old.as_ref().try_into()?),
})
}
};
Ok(proto::ExExNotification { notification: Some(notification) })
}
}
impl TryFrom<&reth::providers::Chain> for proto::Chain {
type Error = eyre::Error;
fn try_from(chain: &reth::providers::Chain) -> Result<Self, Self::Error> {
let bundle_state = chain.execution_outcome().state();
Ok(proto::Chain {
blocks: chain
.blocks_iter()
.map(|block| {
Ok(proto::Block {
header: Some(proto::SealedHeader {
hash: block.header.hash().to_vec(),
header: Some(block.header.header().into()),
}),
body: block
.transactions()
.map(TryInto::try_into)
.collect::<eyre::Result<_>>()?,
ommers: block.ommers.iter().map(Into::into).collect(),
senders: block.senders.iter().map(|sender| sender.to_vec()).collect(),
})
})
.collect::<eyre::Result<_>>()?,
execution_outcome: Some(proto::ExecutionOutcome {
bundle: Some(proto::BundleState {
state: bundle_state
.state
.iter()
.map(|(address, account)| (*address, account).try_into())
.collect::<eyre::Result<_>>()?,
contracts: bundle_state
.contracts
.iter()
.map(|(hash, bytecode)| {
Ok(proto::ContractBytecode {
hash: hash.to_vec(),
bytecode: Some(bytecode.try_into()?),
})
})
.collect::<eyre::Result<_>>()?,
reverts: bundle_state
.reverts
.iter()
.map(|block_reverts| {
Ok(proto::BlockReverts {
reverts: block_reverts
.iter()
.map(|(address, revert)| (*address, revert).try_into())
.collect::<eyre::Result<_>>()?,
})
})
.collect::<eyre::Result<_>>()?,
state_size: bundle_state.state_size as u64,
reverts_size: bundle_state.reverts_size as u64,
}),
receipts: chain
.execution_outcome()
.receipts()
.iter()
.map(|block_receipts| {
Ok(proto::BlockReceipts {
receipts: block_receipts
.iter()
.map(TryInto::try_into)
.collect::<eyre::Result<_>>()?,
})
})
.collect::<eyre::Result<_>>()?,
first_block: chain.execution_outcome().first_block,
}),
})
}
}
impl From<&reth::primitives::Header> for proto::Header {
fn from(header: &reth::primitives::Header) -> Self {
proto::Header {
parent_hash: header.parent_hash.to_vec(),
ommers_hash: header.ommers_hash.to_vec(),
beneficiary: header.beneficiary.to_vec(),
state_root: header.state_root.to_vec(),
transactions_root: header.transactions_root.to_vec(),
receipts_root: header.receipts_root.to_vec(),
withdrawals_root: header.withdrawals_root.map(|root| root.to_vec()),
logs_bloom: header.logs_bloom.to_vec(),
difficulty: header.difficulty.to_le_bytes_vec(),
number: header.number,
gas_limit: header.gas_limit,
gas_used: header.gas_used,
timestamp: header.timestamp,
mix_hash: header.mix_hash.to_vec(),
nonce: header.nonce,
base_fee_per_gas: header.base_fee_per_gas,
blob_gas_used: header.blob_gas_used,
excess_blob_gas: header.excess_blob_gas,
parent_beacon_block_root: header.parent_beacon_block_root.map(|root| root.to_vec()),
extra_data: header.extra_data.to_vec(),
}
}
}
impl TryFrom<&reth::primitives::TransactionSigned> for proto::Transaction {
type Error = eyre::Error;
fn try_from(transaction: &reth::primitives::TransactionSigned) -> Result<Self, Self::Error> {
let hash = transaction.hash().to_vec();
let signature = proto::Signature {
r: transaction.signature.r.to_le_bytes_vec(),
s: transaction.signature.s.to_le_bytes_vec(),
odd_y_parity: transaction.signature.odd_y_parity,
};
let transaction = match &transaction.transaction {
reth::primitives::Transaction::Legacy(reth::primitives::TxLegacy {
chain_id,
nonce,
gas_price,
gas_limit,
to,
value,
input,
}) => proto::transaction::Transaction::Legacy(proto::TransactionLegacy {
chain_id: *chain_id,
nonce: *nonce,
gas_price: gas_price.to_le_bytes().to_vec(),
gas_limit: *gas_limit,
to: Some(to.into()),
value: value.to_le_bytes_vec(),
input: input.to_vec(),
}),
reth::primitives::Transaction::Eip2930(reth::primitives::TxEip2930 {
chain_id,
nonce,
gas_price,
gas_limit,
to,
value,
access_list,
input,
}) => proto::transaction::Transaction::Eip2930(proto::TransactionEip2930 {
chain_id: *chain_id,
nonce: *nonce,
gas_price: gas_price.to_le_bytes().to_vec(),
gas_limit: *gas_limit,
to: Some(to.into()),
value: value.to_le_bytes_vec(),
access_list: access_list.iter().map(Into::into).collect(),
input: input.to_vec(),
}),
reth::primitives::Transaction::Eip1559(reth::primitives::TxEip1559 {
chain_id,
nonce,
gas_limit,
max_fee_per_gas,
max_priority_fee_per_gas,
to,
value,
access_list,
input,
}) => proto::transaction::Transaction::Eip1559(proto::TransactionEip1559 {
chain_id: *chain_id,
nonce: *nonce,
gas_limit: *gas_limit,
max_fee_per_gas: max_fee_per_gas.to_le_bytes().to_vec(),
max_priority_fee_per_gas: max_priority_fee_per_gas.to_le_bytes().to_vec(),
to: Some(to.into()),
value: value.to_le_bytes_vec(),
access_list: access_list.iter().map(Into::into).collect(),
input: input.to_vec(),
}),
reth::primitives::Transaction::Eip4844(reth::primitives::TxEip4844 {
chain_id,
nonce,
gas_limit,
max_fee_per_gas,
max_priority_fee_per_gas,
placeholder: _,
to,
value,
access_list,
blob_versioned_hashes,
max_fee_per_blob_gas,
input,
}) => proto::transaction::Transaction::Eip4844(proto::TransactionEip4844 {
chain_id: *chain_id,
nonce: *nonce,
gas_limit: *gas_limit,
max_fee_per_gas: max_fee_per_gas.to_le_bytes().to_vec(),
max_priority_fee_per_gas: max_priority_fee_per_gas.to_le_bytes().to_vec(),
to: to.to_vec(),
value: value.to_le_bytes_vec(),
access_list: access_list.iter().map(Into::into).collect(),
blob_versioned_hashes: blob_versioned_hashes
.iter()
.map(|hash| hash.to_vec())
.collect(),
max_fee_per_blob_gas: max_fee_per_blob_gas.to_le_bytes().to_vec(),
input: input.to_vec(),
}),
#[cfg(feature = "optimism")]
reth::primitives::Transaction::Deposit(_) => {
eyre::bail!("deposit transaction not supported")
}
};
Ok(proto::Transaction { hash, signature: Some(signature), transaction: Some(transaction) })
}
}
impl From<&reth::primitives::TxKind> for proto::TxKind {
fn from(kind: &reth::primitives::TxKind) -> Self {
proto::TxKind {
kind: match kind {
reth::primitives::TxKind::Create => Some(proto::tx_kind::Kind::Create(())),
reth::primitives::TxKind::Call(address) => {
Some(proto::tx_kind::Kind::Call(address.to_vec()))
}
},
}
}
}
impl From<&reth::primitives::AccessListItem> for proto::AccessListItem {
fn from(item: &reth::primitives::AccessListItem) -> Self {
proto::AccessListItem {
address: item.address.to_vec(),
storage_keys: item.storage_keys.iter().map(|key| key.to_vec()).collect(),
}
}
}
impl TryFrom<(Address, &reth::revm::db::BundleAccount)> for proto::BundleAccount {
type Error = eyre::Error;
fn try_from(
(address, account): (Address, &reth::revm::db::BundleAccount),
) -> Result<Self, Self::Error> {
Ok(proto::BundleAccount {
address: address.to_vec(),
info: account.info.as_ref().map(TryInto::try_into).transpose()?,
original_info: account.original_info.as_ref().map(TryInto::try_into).transpose()?,
storage: account
.storage
.iter()
.map(|(key, slot)| proto::StorageSlot {
key: key.to_le_bytes_vec(),
previous_or_original_value: slot.previous_or_original_value.to_le_bytes_vec(),
present_value: slot.present_value.to_le_bytes_vec(),
})
.collect(),
status: proto::AccountStatus::from(account.status) as i32,
})
}
}
impl TryFrom<&reth::revm::primitives::AccountInfo> for proto::AccountInfo {
type Error = eyre::Error;
fn try_from(account_info: &reth::revm::primitives::AccountInfo) -> Result<Self, Self::Error> {
Ok(proto::AccountInfo {
balance: account_info.balance.to_le_bytes_vec(),
nonce: account_info.nonce,
code_hash: account_info.code_hash.to_vec(),
code: account_info.code.as_ref().map(TryInto::try_into).transpose()?,
})
}
}
impl TryFrom<&reth::revm::primitives::Bytecode> for proto::Bytecode {
type Error = eyre::Error;
fn try_from(bytecode: &reth::revm::primitives::Bytecode) -> Result<Self, Self::Error> {
let bytecode = match bytecode {
reth::revm::primitives::Bytecode::LegacyRaw(code) => {
proto::bytecode::Bytecode::LegacyRaw(code.to_vec())
}
reth::revm::primitives::Bytecode::LegacyAnalyzed(legacy_analyzed) => {
proto::bytecode::Bytecode::LegacyAnalyzed(proto::LegacyAnalyzedBytecode {
bytecode: legacy_analyzed.bytecode().to_vec(),
original_len: legacy_analyzed.original_len() as u64,
jump_table: legacy_analyzed
.jump_table()
.0
.iter()
.by_vals()
.map(|x| x.into())
.collect(),
})
}
reth::revm::primitives::Bytecode::Eof(_) => {
eyre::bail!("EOF bytecode not supported");
}
};
Ok(proto::Bytecode { bytecode: Some(bytecode) })
}
}
impl From<reth::revm::db::AccountStatus> for proto::AccountStatus {
fn from(status: reth::revm::db::AccountStatus) -> Self {
match status {
reth::revm::db::AccountStatus::LoadedNotExisting => {
proto::AccountStatus::LoadedNotExisting
}
reth::revm::db::AccountStatus::Loaded => proto::AccountStatus::Loaded,
reth::revm::db::AccountStatus::LoadedEmptyEIP161 => {
proto::AccountStatus::LoadedEmptyEip161
}
reth::revm::db::AccountStatus::InMemoryChange => proto::AccountStatus::InMemoryChange,
reth::revm::db::AccountStatus::Changed => proto::AccountStatus::Changed,
reth::revm::db::AccountStatus::Destroyed => proto::AccountStatus::Destroyed,
reth::revm::db::AccountStatus::DestroyedChanged => {
proto::AccountStatus::DestroyedChanged
}
reth::revm::db::AccountStatus::DestroyedAgain => proto::AccountStatus::DestroyedAgain,
}
}
}
impl TryFrom<(Address, &reth::revm::db::states::reverts::AccountRevert)> for proto::Revert {
type Error = eyre::Error;
fn try_from(
(address, revert): (Address, &reth::revm::db::states::reverts::AccountRevert),
) -> Result<Self, Self::Error> {
Ok(proto::Revert {
address: address.to_vec(),
account: Some(proto::AccountInfoRevert {
revert: Some(match &revert.account {
reth::revm::db::states::reverts::AccountInfoRevert::DoNothing => {
proto::account_info_revert::Revert::DoNothing(())
}
reth::revm::db::states::reverts::AccountInfoRevert::DeleteIt => {
proto::account_info_revert::Revert::DeleteIt(())
}
reth::revm::db::states::reverts::AccountInfoRevert::RevertTo(account_info) => {
proto::account_info_revert::Revert::RevertTo(account_info.try_into()?)
}
}),
}),
storage: revert
.storage
.iter()
.map(|(key, slot)| {
Ok(proto::RevertToSlot {
key: key.to_le_bytes_vec(),
revert: Some(match slot {
reth::revm::db::RevertToSlot::Some(value) => {
proto::revert_to_slot::Revert::Some(value.to_le_bytes_vec())
}
reth::revm::db::RevertToSlot::Destroyed => {
proto::revert_to_slot::Revert::Destroyed(())
}
}),
})
})
.collect::<eyre::Result<_>>()?,
previous_status: proto::AccountStatus::from(revert.previous_status) as i32,
wipe_storage: revert.wipe_storage,
})
}
}
impl TryFrom<&Option<reth::primitives::Receipt>> for proto::Receipt {
type Error = eyre::Error;
fn try_from(receipt: &Option<reth::primitives::Receipt>) -> Result<Self, Self::Error> {
Ok(proto::Receipt {
receipt: Some(
receipt
.as_ref()
.map_or(eyre::Ok(proto::receipt::Receipt::Empty(())), |receipt| {
Ok(proto::receipt::Receipt::NonEmpty(receipt.try_into()?))
})?,
),
})
}
}
impl TryFrom<&reth::primitives::Receipt> for proto::NonEmptyReceipt {
type Error = eyre::Error;
fn try_from(receipt: &reth::primitives::Receipt) -> Result<Self, Self::Error> {
Ok(proto::NonEmptyReceipt {
tx_type: match receipt.tx_type {
reth::primitives::TxType::Legacy => proto::TxType::Legacy,
reth::primitives::TxType::Eip2930 => proto::TxType::Eip2930,
reth::primitives::TxType::Eip1559 => proto::TxType::Eip1559,
reth::primitives::TxType::Eip4844 => proto::TxType::Eip4844,
#[cfg(feature = "optimism")]
reth::primitives::TxType::Deposit => {
eyre::bail!("deposit transaction not supported")
}
} as i32,
success: receipt.success,
cumulative_gas_used: receipt.cumulative_gas_used,
logs: receipt
.logs
.iter()
.map(|log| proto::Log {
address: log.address.to_vec(),
data: Some(proto::LogData {
topics: log.data.topics().iter().map(|topic| topic.to_vec()).collect(),
data: log.data.data.to_vec(),
}),
})
.collect(),
})
}
}
impl TryFrom<&proto::ExExNotification> for reth_exex::ExExNotification {
type Error = eyre::Error;
fn try_from(notification: &proto::ExExNotification) -> Result<Self, Self::Error> {
Ok(match notification.notification.as_ref().ok_or_eyre("no notification")? {
proto::ex_ex_notification::Notification::ChainCommitted(proto::ChainCommitted {
new,
}) => reth_exex::ExExNotification::ChainCommitted {
new: Arc::new(new.as_ref().ok_or_eyre("no new chain")?.try_into()?),
},
proto::ex_ex_notification::Notification::ChainReorged(proto::ChainReorged {
old,
new,
}) => reth_exex::ExExNotification::ChainReorged {
old: Arc::new(old.as_ref().ok_or_eyre("no old chain")?.try_into()?),
new: Arc::new(new.as_ref().ok_or_eyre("no new chain")?.try_into()?),
},
proto::ex_ex_notification::Notification::ChainReverted(proto::ChainReverted {
old,
}) => reth_exex::ExExNotification::ChainReverted {
old: Arc::new(old.as_ref().ok_or_eyre("no old chain")?.try_into()?),
},
})
}
}
impl TryFrom<&proto::Chain> for reth::providers::Chain {
type Error = eyre::Error;
fn try_from(chain: &proto::Chain) -> Result<Self, Self::Error> {
let execution_outcome =
chain.execution_outcome.as_ref().ok_or_eyre("no execution outcome")?;
let bundle = execution_outcome.bundle.as_ref().ok_or_eyre("no bundle")?;
Ok(reth::providers::Chain::new(
chain.blocks.iter().map(TryInto::try_into).collect::<eyre::Result<Vec<_>>>()?,
reth::providers::ExecutionOutcome {
bundle: reth::revm::db::BundleState {
state: bundle
.state
.iter()
.map(TryInto::try_into)
.collect::<eyre::Result<_>>()?,
contracts: bundle
.contracts
.iter()
.map(|contract| {
Ok((
B256::try_from(contract.hash.as_slice())?,
contract.bytecode.as_ref().ok_or_eyre("no bytecode")?.try_into()?,
))
})
.collect::<eyre::Result<_>>()?,
reverts: reth::revm::db::states::reverts::Reverts::new(
bundle
.reverts
.iter()
.map(|block_reverts| {
block_reverts
.reverts
.iter()
.map(TryInto::try_into)
.collect::<eyre::Result<_>>()
})
.collect::<eyre::Result<_>>()?,
),
state_size: bundle.state_size as usize,
reverts_size: bundle.reverts_size as usize,
},
receipts: reth::primitives::Receipts::from_iter(
execution_outcome
.receipts
.iter()
.map(|block_receipts| {
block_receipts
.receipts
.iter()
.map(TryInto::try_into)
.collect::<eyre::Result<_>>()
})
.collect::<eyre::Result<Vec<_>>>()?,
),
first_block: execution_outcome.first_block,
requests: Default::default(),
},
None,
))
}
}
impl TryFrom<&proto::Block> for reth::primitives::SealedBlockWithSenders {
type Error = eyre::Error;
fn try_from(block: &proto::Block) -> Result<Self, Self::Error> {
let sealed_header = block.header.as_ref().ok_or_eyre("no sealed header")?;
let header = sealed_header.header.as_ref().ok_or_eyre("no header")?.try_into()?;
let sealed_header = reth::primitives::SealedHeader::new(
header,
BlockHash::try_from(sealed_header.hash.as_slice())?,
);
let transactions = block.body.iter().map(TryInto::try_into).collect::<eyre::Result<_>>()?;
let ommers = block.ommers.iter().map(TryInto::try_into).collect::<eyre::Result<_>>()?;
let senders = block
.senders
.iter()
.map(|sender| Address::try_from(sender.as_slice()))
.collect::<Result<_, _>>()?;
reth::primitives::SealedBlockWithSenders::new(
reth::primitives::SealedBlock::new(
sealed_header,
reth::primitives::BlockBody {
transactions,
ommers,
withdrawals: Default::default(),
requests: Default::default(),
},
),
senders,
)
.ok_or_eyre("senders do not match transactions")
}
}
impl TryFrom<&proto::Header> for reth::primitives::Header {
type Error = eyre::Error;
fn try_from(header: &proto::Header) -> Result<Self, Self::Error> {
Ok(reth::primitives::Header {
parent_hash: B256::try_from(header.parent_hash.as_slice())?,
ommers_hash: B256::try_from(header.ommers_hash.as_slice())?,
beneficiary: Address::try_from(header.beneficiary.as_slice())?,
state_root: B256::try_from(header.state_root.as_slice())?,
transactions_root: B256::try_from(header.transactions_root.as_slice())?,
receipts_root: B256::try_from(header.receipts_root.as_slice())?,
withdrawals_root: header
.withdrawals_root
.as_ref()
.map(|root| B256::try_from(root.as_slice()))
.transpose()?,
logs_bloom: Bloom::try_from(header.logs_bloom.as_slice())?,
difficulty: U256::try_from_le_slice(&header.difficulty)
.ok_or_eyre("failed to parse difficulty")?,
number: header.number,
gas_limit: header.gas_limit,
gas_used: header.gas_used,
timestamp: header.timestamp,
mix_hash: B256::try_from(header.mix_hash.as_slice())?,
nonce: header.nonce,
base_fee_per_gas: header.base_fee_per_gas,
blob_gas_used: header.blob_gas_used,
excess_blob_gas: header.excess_blob_gas,
parent_beacon_block_root: header
.parent_beacon_block_root
.as_ref()
.map(|root| B256::try_from(root.as_slice()))
.transpose()?,
requests_root: None,
extra_data: header.extra_data.as_slice().to_vec().into(),
})
}
}
impl TryFrom<&proto::Transaction> for reth::primitives::TransactionSigned {
type Error = eyre::Error;
fn try_from(transaction: &proto::Transaction) -> Result<Self, Self::Error> {
let hash = TxHash::try_from(transaction.hash.as_slice())?;
let signature = transaction.signature.as_ref().ok_or_eyre("no signature")?;
let signature = reth::primitives::Signature {
r: U256::try_from_le_slice(signature.r.as_slice()).ok_or_eyre("failed to parse r")?,
s: U256::try_from_le_slice(signature.s.as_slice()).ok_or_eyre("failed to parse s")?,
odd_y_parity: signature.odd_y_parity,
};
let transaction = match transaction.transaction.as_ref().ok_or_eyre("no transaction")? {
proto::transaction::Transaction::Legacy(proto::TransactionLegacy {
chain_id,
nonce,
gas_price,
gas_limit,
to,
value,
input,
}) => reth::primitives::Transaction::Legacy(reth::primitives::TxLegacy {
chain_id: *chain_id,
nonce: *nonce,
gas_price: u128::from_le_bytes(gas_price.as_slice().try_into()?),
gas_limit: *gas_limit,
to: to.as_ref().ok_or_eyre("no to")?.try_into()?,
value: U256::try_from_le_slice(value.as_slice())
.ok_or_eyre("failed to parse value")?,
input: input.to_vec().into(),
}),
proto::transaction::Transaction::Eip2930(proto::TransactionEip2930 {
chain_id,
nonce,
gas_price,
gas_limit,
to,
value,
access_list,
input,
}) => reth::primitives::Transaction::Eip2930(reth::primitives::TxEip2930 {
chain_id: *chain_id,
nonce: *nonce,
gas_price: u128::from_le_bytes(gas_price.as_slice().try_into()?),
gas_limit: *gas_limit,
to: to.as_ref().ok_or_eyre("no to")?.try_into()?,
value: U256::try_from_le_slice(value.as_slice())
.ok_or_eyre("failed to parse value")?,
access_list: access_list
.iter()
.map(TryInto::try_into)
.collect::<eyre::Result<Vec<_>>>()?
.into(),
input: input.to_vec().into(),
}),
proto::transaction::Transaction::Eip1559(proto::TransactionEip1559 {
chain_id,
nonce,
gas_limit,
max_fee_per_gas,
max_priority_fee_per_gas,
to,
value,
access_list,
input,
}) => reth::primitives::Transaction::Eip1559(reth::primitives::TxEip1559 {
chain_id: *chain_id,
nonce: *nonce,
gas_limit: *gas_limit,
max_fee_per_gas: u128::from_le_bytes(max_fee_per_gas.as_slice().try_into()?),
max_priority_fee_per_gas: u128::from_le_bytes(
max_priority_fee_per_gas.as_slice().try_into()?,
),
to: to.as_ref().ok_or_eyre("no to")?.try_into()?,
value: U256::try_from_le_slice(value.as_slice())
.ok_or_eyre("failed to parse value")?,
access_list: access_list
.iter()
.map(TryInto::try_into)
.collect::<eyre::Result<Vec<_>>>()?
.into(),
input: input.to_vec().into(),
}),
proto::transaction::Transaction::Eip4844(proto::TransactionEip4844 {
chain_id,
nonce,
gas_limit,
max_fee_per_gas,
max_priority_fee_per_gas,
to,
value,
access_list,
blob_versioned_hashes,
max_fee_per_blob_gas,
input,
}) => reth::primitives::Transaction::Eip4844(reth::primitives::TxEip4844 {
chain_id: *chain_id,
nonce: *nonce,
gas_limit: *gas_limit,
max_fee_per_gas: u128::from_le_bytes(max_fee_per_gas.as_slice().try_into()?),
max_priority_fee_per_gas: u128::from_le_bytes(
max_priority_fee_per_gas.as_slice().try_into()?,
),
placeholder: None,
to: Address::try_from(to.as_slice())?,
value: U256::try_from_le_slice(value.as_slice())
.ok_or_eyre("failed to parse value")?,
access_list: access_list
.iter()
.map(TryInto::try_into)
.collect::<eyre::Result<Vec<_>>>()?
.into(),
blob_versioned_hashes: blob_versioned_hashes
.iter()
.map(|hash| B256::try_from(hash.as_slice()))
.collect::<Result<_, _>>()?,
max_fee_per_blob_gas: u128::from_le_bytes(
max_fee_per_blob_gas.as_slice().try_into()?,
),
input: input.to_vec().into(),
}),
};
Ok(reth::primitives::TransactionSigned { hash, signature, transaction })
}
}
impl TryFrom<&proto::TxKind> for reth::primitives::TxKind {
type Error = eyre::Error;
fn try_from(tx_kind: &proto::TxKind) -> Result<Self, Self::Error> {
Ok(match tx_kind.kind.as_ref().ok_or_eyre("no kind")? {
proto::tx_kind::Kind::Create(()) => reth::primitives::TxKind::Create,
proto::tx_kind::Kind::Call(address) => {
reth::primitives::TxKind::Call(Address::try_from(address.as_slice())?)
}
})
}
}
impl TryFrom<&proto::AccessListItem> for reth::primitives::AccessListItem {
type Error = eyre::Error;
fn try_from(item: &proto::AccessListItem) -> Result<Self, Self::Error> {
Ok(reth::primitives::AccessListItem {
address: Address::try_from(item.address.as_slice())?,
storage_keys: item
.storage_keys
.iter()
.map(|key| B256::try_from(key.as_slice()))
.collect::<Result<_, _>>()?,
})
}
}
impl TryFrom<&proto::AccountInfo> for reth::revm::primitives::AccountInfo {
type Error = eyre::Error;
fn try_from(account_info: &proto::AccountInfo) -> Result<Self, Self::Error> {
Ok(reth::revm::primitives::AccountInfo {
balance: U256::try_from_le_slice(account_info.balance.as_slice())
.ok_or_eyre("failed to parse balance")?,
nonce: account_info.nonce,
code_hash: B256::try_from(account_info.code_hash.as_slice())?,
code: account_info.code.as_ref().map(TryInto::try_into).transpose()?,
})
}
}
impl TryFrom<&proto::Bytecode> for reth::revm::primitives::Bytecode {
type Error = eyre::Error;
fn try_from(bytecode: &proto::Bytecode) -> Result<Self, Self::Error> {
Ok(match bytecode.bytecode.as_ref().ok_or_eyre("no bytecode")? {
proto::bytecode::Bytecode::LegacyRaw(code) => {
reth::revm::primitives::Bytecode::LegacyRaw(code.clone().into())
}
proto::bytecode::Bytecode::LegacyAnalyzed(legacy_analyzed) => {
reth::revm::primitives::Bytecode::LegacyAnalyzed(
reth::revm::primitives::LegacyAnalyzedBytecode::new(
legacy_analyzed.bytecode.clone().into(),
legacy_analyzed.original_len as usize,
reth::revm::primitives::JumpTable::from_slice(
legacy_analyzed
.jump_table
.iter()
.map(|dest| *dest as u8)
.collect::<Vec<_>>()
.as_slice(),
),
),
)
}
})
}
}
impl From<proto::AccountStatus> for reth::revm::db::AccountStatus {
fn from(status: proto::AccountStatus) -> Self {
match status {
proto::AccountStatus::LoadedNotExisting => {
reth::revm::db::AccountStatus::LoadedNotExisting
}
proto::AccountStatus::Loaded => reth::revm::db::AccountStatus::Loaded,
proto::AccountStatus::LoadedEmptyEip161 => {
reth::revm::db::AccountStatus::LoadedEmptyEIP161
}
proto::AccountStatus::InMemoryChange => reth::revm::db::AccountStatus::InMemoryChange,
proto::AccountStatus::Changed => reth::revm::db::AccountStatus::Changed,
proto::AccountStatus::Destroyed => reth::revm::db::AccountStatus::Destroyed,
proto::AccountStatus::DestroyedChanged => {
reth::revm::db::AccountStatus::DestroyedChanged
}
proto::AccountStatus::DestroyedAgain => reth::revm::db::AccountStatus::DestroyedAgain,
}
}
}
impl TryFrom<&proto::BundleAccount> for (Address, reth::revm::db::BundleAccount) {
type Error = eyre::Error;
fn try_from(account: &proto::BundleAccount) -> Result<Self, Self::Error> {
Ok((
Address::try_from(account.address.as_slice())?,
reth::revm::db::BundleAccount {
info: account.info.as_ref().map(TryInto::try_into).transpose()?,
original_info: account.original_info.as_ref().map(TryInto::try_into).transpose()?,
storage: account
.storage
.iter()
.map(|slot| {
Ok((
U256::try_from_le_slice(slot.key.as_slice())
.ok_or_eyre("failed to parse key")?,
reth::revm::db::states::StorageSlot {
previous_or_original_value: U256::try_from_le_slice(
slot.previous_or_original_value.as_slice(),
)
.ok_or_eyre("failed to parse previous or original value")?,
present_value: U256::try_from_le_slice(
slot.present_value.as_slice(),
)
.ok_or_eyre("failed to parse present value")?,
},
))
})
.collect::<eyre::Result<_>>()?,
status: proto::AccountStatus::try_from(account.status)?.into(),
},
))
}
}
impl TryFrom<&proto::Revert> for (Address, reth::revm::db::states::reverts::AccountRevert) {
type Error = eyre::Error;
fn try_from(revert: &proto::Revert) -> Result<Self, Self::Error> {
Ok((
Address::try_from(revert.address.as_slice())?,
reth::revm::db::states::reverts::AccountRevert {
account: match revert
.account
.as_ref()
.ok_or_eyre("no revert account")?
.revert
.as_ref()
.ok_or_eyre("no revert account revert")?
{
proto::account_info_revert::Revert::DoNothing(()) => {
reth::revm::db::states::reverts::AccountInfoRevert::DoNothing
}
proto::account_info_revert::Revert::DeleteIt(()) => {
reth::revm::db::states::reverts::AccountInfoRevert::DeleteIt
}
proto::account_info_revert::Revert::RevertTo(account_info) => {
reth::revm::db::states::reverts::AccountInfoRevert::RevertTo(
account_info.try_into()?,
)
}
},
storage: revert
.storage
.iter()
.map(|slot| {
Ok((
U256::try_from_le_slice(slot.key.as_slice())
.ok_or_eyre("failed to parse slot key")?,
match slot.revert.as_ref().ok_or_eyre("no slot revert")? {
proto::revert_to_slot::Revert::Some(value) => {
reth::revm::db::states::reverts::RevertToSlot::Some(
U256::try_from_le_slice(value.as_slice())
.ok_or_eyre("failed to parse slot revert")?,
)
}
proto::revert_to_slot::Revert::Destroyed(()) => {
reth::revm::db::states::reverts::RevertToSlot::Destroyed
}
},
))
})
.collect::<eyre::Result<_>>()?,
previous_status: proto::AccountStatus::try_from(revert.previous_status)?.into(),
wipe_storage: revert.wipe_storage,
},
))
}
}
impl TryFrom<&proto::Receipt> for Option<reth::primitives::Receipt> {
type Error = eyre::Error;
fn try_from(receipt: &proto::Receipt) -> Result<Self, Self::Error> {
Ok(match receipt.receipt.as_ref().ok_or_eyre("no receipt")? {
proto::receipt::Receipt::Empty(()) => None,
proto::receipt::Receipt::NonEmpty(receipt) => Some(receipt.try_into()?),
})
}
}
impl TryFrom<&proto::NonEmptyReceipt> for reth::primitives::Receipt {
type Error = eyre::Error;
fn try_from(receipt: &proto::NonEmptyReceipt) -> Result<Self, Self::Error> {
Ok(reth::primitives::Receipt {
tx_type: match proto::TxType::try_from(receipt.tx_type)? {
proto::TxType::Legacy => reth::primitives::TxType::Legacy,
proto::TxType::Eip2930 => reth::primitives::TxType::Eip2930,
proto::TxType::Eip1559 => reth::primitives::TxType::Eip1559,
proto::TxType::Eip4844 => reth::primitives::TxType::Eip4844,
},
success: receipt.success,
cumulative_gas_used: receipt.cumulative_gas_used,
logs: receipt
.logs
.iter()
.map(|log| {
let data = log.data.as_ref().ok_or_eyre("no log data")?;
Ok(reth::primitives::Log {
address: Address::try_from(log.address.as_slice())?,
data: reth::primitives::LogData::new_unchecked(
data.topics
.iter()
.map(|topic| Ok(B256::try_from(topic.as_slice())?))
.collect::<eyre::Result<_>>()?,
data.data.clone().into(),
),
})
})
.collect::<eyre::Result<_>>()?,
#[cfg(feature = "optimism")]
deposit_nonce: None,
#[cfg(feature = "optimism")]
deposit_receipt_version: None,
})
}
}

View File

@ -1,4 +0,0 @@
pub mod codec;
pub mod proto {
tonic::include_proto!("exex");
}