Skip to content
This repository has been archived by the owner on Aug 28, 2024. It is now read-only.

Commit

Permalink
feat: Adding unstable RPC endpoint to return the execution_info (matt…
Browse files Browse the repository at this point in the history
…er-labs#2332)

## What ❔

* Execution info shows some details from the VM execution (like
circutits used, pubdata etc)
* This data was only stored in DB and not accessible outside - after
this PR, it is available under `nstable_getTransactionExecutionInfo`

## Why ❔

* This allows us to do more advanced debugging of issues - especially
for cases where we might not have access to the underlying database.
* In the future, some parts of this might be migrated into a 'stable'
RPC.

## Evidence

![image](https://github.com/matter-labs/zksync-era/assets/128217157/20da9e80-f7b3-4614-89f3-b09a774ffcf9)
  • Loading branch information
mm-zk authored and irnb committed Jul 12, 2024
1 parent 20998a8 commit 56b4219
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 9 deletions.

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

8 changes: 8 additions & 0 deletions core/lib/dal/src/models/storage_transaction.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{convert::TryInto, str::FromStr};

use bigdecimal::Zero;
use serde_json::Value;
use sqlx::types::chrono::{DateTime, NaiveDateTime, Utc};
use zksync_types::{
api::{self, TransactionDetails, TransactionReceipt, TransactionStatus},
Expand Down Expand Up @@ -396,6 +397,13 @@ impl From<StorageTransactionReceipt> for TransactionReceipt {
}
}

/// Details of the transaction execution.
#[derive(Debug, Clone, sqlx::FromRow)]
pub struct StorageTransactionExecutionInfo {
/// This is an opaque JSON field, with VM version specific contents.
pub execution_info: Value,
}

#[derive(Debug, Clone, sqlx::FromRow)]
pub(crate) struct StorageTransactionDetails {
pub is_priority: bool,
Expand Down
40 changes: 39 additions & 1 deletion core/lib/dal/src/transactions_web3_dal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use zksync_types::{
use crate::{
models::storage_transaction::{
StorageApiTransaction, StorageTransaction, StorageTransactionDetails,
StorageTransactionReceipt,
StorageTransactionExecutionInfo, StorageTransactionReceipt,
},
Core, CoreDal,
};
Expand Down Expand Up @@ -151,6 +151,29 @@ impl TransactionsWeb3Dal<'_, '_> {
.await
}

pub async fn get_unstable_transaction_execution_info(
&mut self,
hash: H256,
) -> DalResult<Option<serde_json::Value>> {
let row = sqlx::query_as!(
StorageTransactionExecutionInfo,
r#"
SELECT
transactions.execution_info
FROM
transactions
WHERE
transactions.hash = $1
"#,
hash.as_bytes()
)
.instrument("get_unstable_transaction_execution_info")
.with_arg("hash", &hash)
.fetch_optional(self.storage)
.await?;
Ok(row.map(|entry| entry.execution_info))
}

async fn get_transactions_inner(
&mut self,
selector: TransactionSelector<'_>,
Expand Down Expand Up @@ -550,6 +573,21 @@ mod tests {
.get_transaction_by_hash(H256::zero(), L2ChainId::from(270))
.await;
assert!(web3_tx.unwrap().is_none());

let execution_info = conn
.transactions_web3_dal()
.get_unstable_transaction_execution_info(tx_hash)
.await
.unwrap()
.expect("Transaction execution info is missing in the DAL");

// Check that execution info has at least the circuit statistics field.
// If this assertion fails because the transaction execution info format
// has changed, replace circuit_statistic with any other valid field
assert!(
execution_info.get("circuit_statistic").is_some(),
"Missing circuit_statistics field"
);
}

#[tokio::test]
Expand Down
9 changes: 9 additions & 0 deletions core/lib/types/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use chrono::{DateTime, Utc};
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use serde_json::Value;
use strum::Display;
use zksync_basic_types::{
web3::{AccessList, Bytes, Index},
Expand Down Expand Up @@ -821,6 +822,14 @@ pub struct ApiStorageLog {
pub written_value: U256,
}

/// Raw transaction execution data.
/// Data is taken from `TransactionExecutionMetrics`.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TransactionExecutionInfo {
pub execution_info: Value,
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
7 changes: 4 additions & 3 deletions core/lib/web3_decl/src/namespaces/mod.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
pub use self::{
debug::DebugNamespaceClient, en::EnNamespaceClient, eth::EthNamespaceClient,
net::NetNamespaceClient, snapshots::SnapshotsNamespaceClient, web3::Web3NamespaceClient,
zks::ZksNamespaceClient,
net::NetNamespaceClient, snapshots::SnapshotsNamespaceClient,
unstable::UnstableNamespaceClient, web3::Web3NamespaceClient, zks::ZksNamespaceClient,
};
#[cfg(feature = "server")]
pub use self::{
debug::DebugNamespaceServer, en::EnNamespaceServer, eth::EthNamespaceServer,
eth::EthPubSubServer, net::NetNamespaceServer, snapshots::SnapshotsNamespaceServer,
web3::Web3NamespaceServer, zks::ZksNamespaceServer,
unstable::UnstableNamespaceServer, web3::Web3NamespaceServer, zks::ZksNamespaceServer,
};

mod debug;
mod en;
mod eth;
mod net;
mod snapshots;
mod unstable;
mod web3;
mod zks;
23 changes: 23 additions & 0 deletions core/lib/web3_decl/src/namespaces/unstable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#[cfg_attr(not(feature = "server"), allow(unused_imports))]
use jsonrpsee::core::RpcResult;
use jsonrpsee::proc_macros::rpc;
use zksync_types::{api::TransactionExecutionInfo, H256};

use crate::client::{ForNetwork, L2};

/// RPCs in this namespace are experimental, and their interface is unstable, and it WILL change.
#[cfg_attr(
feature = "server",
rpc(server, client, namespace = "unstable", client_bounds(Self: ForNetwork<Net = L2>))
)]
#[cfg_attr(
not(feature = "server"),
rpc(client, namespace = "unstable", client_bounds(Self: ForNetwork<Net = L2>))
)]
pub trait UnstableNamespace {
#[method(name = "getTransactionExecutionInfo")]
async fn transaction_execution_info(
&self,
hash: H256,
) -> RpcResult<Option<TransactionExecutionInfo>>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ pub mod en;
pub mod eth;
pub mod net;
pub mod snapshots;
pub mod unstable;
pub mod web3;
pub mod zks;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use zksync_types::{api::TransactionExecutionInfo, H256};
use zksync_web3_decl::{
jsonrpsee::core::{async_trait, RpcResult},
namespaces::UnstableNamespaceServer,
};

use crate::web3::namespaces::UnstableNamespace;

#[async_trait]
impl UnstableNamespaceServer for UnstableNamespace {
async fn transaction_execution_info(
&self,
hash: H256,
) -> RpcResult<Option<TransactionExecutionInfo>> {
self.transaction_execution_info_impl(hash)
.await
.map_err(|err| self.current_method().map_err(err))
}
}
14 changes: 10 additions & 4 deletions core/node/api_server/src/web3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ use zksync_web3_decl::{
},
namespaces::{
DebugNamespaceServer, EnNamespaceServer, EthNamespaceServer, EthPubSubServer,
NetNamespaceServer, SnapshotsNamespaceServer, Web3NamespaceServer, ZksNamespaceServer,
NetNamespaceServer, SnapshotsNamespaceServer, UnstableNamespaceServer, Web3NamespaceServer,
ZksNamespaceServer,
},
types::Filter,
};
Expand All @@ -37,8 +38,8 @@ use self::{
mempool_cache::MempoolCache,
metrics::API_METRICS,
namespaces::{
DebugNamespace, EnNamespace, EthNamespace, NetNamespace, SnapshotsNamespace, Web3Namespace,
ZksNamespace,
DebugNamespace, EnNamespace, EthNamespace, NetNamespace, SnapshotsNamespace,
UnstableNamespace, Web3Namespace, ZksNamespace,
},
pubsub::{EthSubscribe, EthSubscriptionIdProvider, PubSubEvent},
state::{Filters, InternalApiConfig, RpcState, SealedL2BlockNumber},
Expand Down Expand Up @@ -98,6 +99,7 @@ pub enum Namespace {
En,
Pubsub,
Snapshots,
Unstable,
}

impl Namespace {
Expand Down Expand Up @@ -407,9 +409,13 @@ impl ApiServer {
.context("cannot merge en namespace")?;
}
if namespaces.contains(&Namespace::Snapshots) {
rpc.merge(SnapshotsNamespace::new(rpc_state).into_rpc())
rpc.merge(SnapshotsNamespace::new(rpc_state.clone()).into_rpc())
.context("cannot merge snapshots namespace")?;
}
if namespaces.contains(&Namespace::Unstable) {
rpc.merge(UnstableNamespace::new(rpc_state).into_rpc())
.context("cannot merge unstable namespace")?;
}
Ok(rpc)
}

Expand Down
4 changes: 3 additions & 1 deletion core/node/api_server/src/web3/namespaces/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ mod en;
pub(crate) mod eth;
mod net;
mod snapshots;
mod unstable;
mod web3;
mod zks;

pub(super) use self::{
debug::DebugNamespace, en::EnNamespace, eth::EthNamespace, net::NetNamespace,
snapshots::SnapshotsNamespace, web3::Web3Namespace, zks::ZksNamespace,
snapshots::SnapshotsNamespace, unstable::UnstableNamespace, web3::Web3Namespace,
zks::ZksNamespace,
};
33 changes: 33 additions & 0 deletions core/node/api_server/src/web3/namespaces/unstable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use zksync_dal::{CoreDal, DalError};
use zksync_types::api::TransactionExecutionInfo;
use zksync_web3_decl::{error::Web3Error, types::H256};

use crate::web3::{backend_jsonrpsee::MethodTracer, RpcState};

#[derive(Debug)]
pub(crate) struct UnstableNamespace {
state: RpcState,
}

impl UnstableNamespace {
pub fn new(state: RpcState) -> Self {
Self { state }
}

pub(crate) fn current_method(&self) -> &MethodTracer {
&self.state.current_method
}

pub async fn transaction_execution_info_impl(
&self,
hash: H256,
) -> Result<Option<TransactionExecutionInfo>, Web3Error> {
let mut storage = self.state.acquire_connection().await?;
Ok(storage
.transactions_web3_dal()
.get_unstable_transaction_execution_info(hash)
.await
.map_err(DalError::generalize)?
.map(|execution_info| TransactionExecutionInfo { execution_info }))
}
}

0 comments on commit 56b4219

Please sign in to comment.