Skip to content

fix(l1,l2): eth client send blobs when calling eth_estimateGas #3540

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 8, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions crates/networking/rpc/clients/eth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,11 @@ impl EthClient {
for url in self.urls.iter() {
response = self.send_request_to_url(url, &request).await;
if response.is_ok() {
return response;
// Some RPC servers don't implement all the endpoints or don't implement them completely/correctly
// so if the server returns Ok(RpcResponse::Error) we retry with the others
if let Ok(RpcResponse::Success(ref _a)) = response {
return response;
}
}
}
response
Expand Down Expand Up @@ -436,6 +440,20 @@ impl EthClient {
);
}

if !transaction.blobs.is_empty() {
let blobs_str: Vec<_> = transaction
.blobs
.into_iter()
.map(|blob| format!("0x{}", hex::encode(blob)))
.collect();

data.as_object_mut()
.ok_or_else(|| {
EthClientError::Custom("Failed to mutate data in estimate_gas".to_owned())
})?
.insert("blobs".to_owned(), json!(blobs_str));
}

// Add the nonce just if present, otherwise the RPC will use the latest nonce
if let Some(nonce) = transaction.nonce {
if let Value::Object(ref mut map) = data {
Expand Down Expand Up @@ -843,7 +861,9 @@ impl EthClient {
) -> Result<(), EthClientError> {
let mut transaction = match wrapped_tx {
WrappedTransaction::EIP4844(wrapped_eip4844_transaction) => {
GenericTransaction::from(wrapped_eip4844_transaction.clone().tx)
let mut tx = GenericTransaction::from(wrapped_eip4844_transaction.clone().tx);
add_blobs_to_generic_tx(&mut tx, &wrapped_eip4844_transaction.blobs_bundle);
tx
}
WrappedTransaction::EIP1559(eip1559_transaction) => {
GenericTransaction::from(eip1559_transaction.clone())
Expand Down Expand Up @@ -877,7 +897,9 @@ impl EthClient {
) -> Result<u64, EthClientError> {
let mut transaction = match wrapped_tx {
WrappedTransaction::EIP4844(wrapped_eip4844_transaction) => {
GenericTransaction::from(wrapped_eip4844_transaction.clone().tx)
let mut tx = GenericTransaction::from(wrapped_eip4844_transaction.clone().tx);
add_blobs_to_generic_tx(&mut tx, &wrapped_eip4844_transaction.blobs_bundle);
tx
}
WrappedTransaction::EIP1559(eip1559_transaction) => {
GenericTransaction::from(eip1559_transaction.clone())
Expand Down Expand Up @@ -1423,6 +1445,14 @@ pub fn get_address_from_secret_key(secret_key: &SecretKey) -> Result<Address, Et
Ok(Address::from(address_bytes))
}

pub fn add_blobs_to_generic_tx(tx: &mut GenericTransaction, bundle: &BlobsBundle) {
tx.blobs = bundle
.blobs
.iter()
.map(|blob| Bytes::copy_from_slice(blob))
.collect()
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct GetTransactionByHashTransaction {
Expand Down