Skip to content

Commit

Permalink
Update queries
Browse files Browse the repository at this point in the history
Signed-off-by: Danil <deniallugo@gmail.com>
  • Loading branch information
Deniallugo committed Sep 24, 2024
1 parent 8fa81cc commit 618bf1a
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 117 deletions.

This file was deleted.

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

14 changes: 10 additions & 4 deletions core/lib/dal/src/transactions_dal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2113,11 +2113,12 @@ impl TransactionsDal<'_, '_> {
Ok(data)
}

pub async fn get_call_trace(&mut self, tx_hash: H256) -> DalResult<Option<Call>> {
pub async fn get_call_trace(&mut self, tx_hash: H256) -> DalResult<Option<(Call, usize)>> {
let row = sqlx::query!(
r#"
SELECT
protocol_version
protocol_version,
index_in_block
FROM
transactions
INNER JOIN miniblocks ON transactions.miniblock_number = miniblocks.number
Expand Down Expand Up @@ -2155,7 +2156,12 @@ impl TransactionsDal<'_, '_> {
.with_arg("tx_hash", &tx_hash)
.fetch_optional(self.storage)
.await?
.map(|call_trace| parse_call_trace(&call_trace.call_trace, protocol_version)))
.map(|call_trace| {
(
parse_call_trace(&call_trace.call_trace, protocol_version),
row.index_in_block.unwrap_or_default() as usize,
)
}))
}

pub(crate) async fn get_tx_by_hash(&mut self, hash: H256) -> DalResult<Option<Transaction>> {
Expand Down Expand Up @@ -2227,7 +2233,7 @@ mod tests {
.await
.unwrap();

let call_trace = conn
let (call_trace, _) = conn
.transactions_dal()
.get_call_trace(tx_hash)
.await
Expand Down
52 changes: 51 additions & 1 deletion core/lib/types/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,17 @@ pub struct TracerConfig {
pub tracer_config: CallTracerConfig,
}

impl Default for TracerConfig {
fn default() -> Self {
TracerConfig {
tracer: SupportedTracers::CallTracer,
tracer_config: CallTracerConfig {
only_top_call: false,
},
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum BlockStatus {
Expand All @@ -741,12 +752,51 @@ pub enum CallTracerBlockResult {
CallTrace(Vec<ResultDebugCall>),
FlatCallTrace(Vec<DebugCallFlat>),
}
impl CallTracerBlockResult {
pub fn unwrap_flatten(self) -> Vec<DebugCallFlat> {
match self {
Self::CallTrace(_) => {
unreachable!()
}
Self::FlatCallTrace(a) => a,
}
}

pub fn unwrap_default(self) -> Vec<ResultDebugCall> {
match self {
Self::CallTrace(a) => a,
Self::FlatCallTrace(_) => {
unreachable!()
}
}
}
}

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(untagged)]
pub enum CallTracerResult {
CallTrace(DebugCall),
FlattCallTrace(Vec<DebugCallFlat>),
FlatCallTrace(Vec<DebugCallFlat>),
}

impl CallTracerResult {
pub fn unwrap_flatten(self) -> Vec<DebugCallFlat> {
match self {
Self::CallTrace(_) => {
unreachable!()
}
Self::FlatCallTrace(a) => a,
}
}

pub fn unwrap_default(self) -> DebugCall {
match self {
Self::CallTrace(a) => a,
Self::FlatCallTrace(_) => {
unreachable!()
}
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down
2 changes: 1 addition & 1 deletion core/lib/types/src/debug_flat_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub struct DebugCallFlat {
pub action: Action,
pub result: Option<CallResult>,
pub subtraces: usize,
pub traceaddress: Vec<usize>,
pub trace_address: Vec<usize>,
pub transaction_position: usize,
pub transaction_hash: H256,
pub r#type: DebugCallType,
Expand Down
101 changes: 57 additions & 44 deletions core/node/api_server/src/web3/namespaces/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,30 +49,26 @@ impl DebugNamespace {
call: Call,
index: usize,
transaction_hash: H256,
tracer_option: Option<TracerConfig>,
tracer_option: TracerConfig,
) -> CallTracerResult {
let (only_top_call, flatten) = tracer_option
.map(|options| {
(
options.tracer_config.only_top_call,
matches!(options.tracer, SupportedTracers::FlatCallTracer),
)
})
.unwrap_or((false, false));
if flatten {
let mut calls = vec![];
let mut traces = vec![index];
Self::map_flatten_call(
match tracer_option.tracer {
SupportedTracers::CallTracer => CallTracerResult::CallTrace(Self::map_default_call(
call,
&mut calls,
&mut traces,
only_top_call,
index,
transaction_hash,
);
CallTracerResult::FlattCallTrace(calls)
} else {
CallTracerResult::CallTrace(Self::map_default_call(call, only_top_call))
tracer_option.tracer_config.only_top_call,
)),
SupportedTracers::FlatCallTracer => {
let mut calls = vec![];
let mut traces = vec![index];
Self::flatten_call(
call,
&mut calls,
&mut traces,
tracer_option.tracer_config.only_top_call,
index,
transaction_hash,
);
CallTracerResult::FlatCallTrace(calls)
}
}
}
pub(crate) fn map_default_call(call: Call, only_top_call: bool) -> DebugCall {
Expand Down Expand Up @@ -104,7 +100,7 @@ impl DebugNamespace {
}
}

fn map_flatten_call(
fn flatten_call(
call: Call,
calls: &mut Vec<DebugCallFlat>,
trace_address: &mut Vec<usize>,
Expand Down Expand Up @@ -139,7 +135,7 @@ impl DebugNamespace {
},
result,
subtraces,
traceaddress: trace_address.clone(), // Clone the current trace address
trace_address: trace_address.clone(), // Clone the current trace address
transaction_position,
transaction_hash,
r#type: DebugCallType::Call,
Expand All @@ -148,7 +144,7 @@ impl DebugNamespace {
if !only_top_call {
for (number, call) in call.calls.into_iter().enumerate() {
trace_address.push(number);
Self::map_flatten_call(
Self::flatten_call(
call,
calls,
trace_address,
Expand Down Expand Up @@ -187,20 +183,33 @@ impl DebugNamespace {
.await
.map_err(DalError::generalize)?;

let mut calls = vec![];
let mut flat_calls = vec![];
for (call_trace, hash, index) in call_traces {
match Self::map_call(call_trace, index, hash, options) {
CallTracerResult::CallTrace(call) => calls.push(ResultDebugCall { result: call }),
CallTracerResult::FlattCallTrace(mut call) => flat_calls.append(&mut call),
let options = options.unwrap_or_default();
let result = match options.tracer {
SupportedTracers::CallTracer => CallTracerBlockResult::CallTrace(
call_traces
.into_iter()
.map(|(call, _, _)| ResultDebugCall {
result: Self::map_default_call(call, options.tracer_config.only_top_call),
})
.collect(),
),
SupportedTracers::FlatCallTracer => {
let mut flat_calls = vec![];
for (call, tx_hash, tx_index) in call_traces {
let mut traces = vec![tx_index];
Self::flatten_call(
call,
&mut flat_calls,
&mut traces,
options.tracer_config.only_top_call,
tx_index,
tx_hash,
);
}
CallTracerBlockResult::FlatCallTrace(flat_calls)
}
}

if calls.is_empty() && !flat_calls.is_empty() {
Ok(CallTracerBlockResult::FlatCallTrace(flat_calls))
} else {
Ok(CallTracerBlockResult::CallTrace(calls))
}
};
Ok(result)
}

pub async fn debug_trace_transaction_impl(
Expand All @@ -214,7 +223,14 @@ impl DebugNamespace {
.get_call_trace(tx_hash)
.await
.map_err(DalError::generalize)?;
Ok(call_trace.map(|call_trace| Self::map_call(call_trace, 0, tx_hash, options)))
Ok(call_trace.map(|(call_trace, index_in_block)| {
Self::map_call(
call_trace,
index_in_block,
tx_hash,
options.unwrap_or_default(),
)
}))
}

pub async fn debug_trace_call_impl(
Expand All @@ -226,10 +242,7 @@ impl DebugNamespace {
let block_id = block_id.unwrap_or(BlockId::Number(BlockNumber::Pending));
self.current_method().set_block_id(block_id);

let only_top_call = options
.as_ref()
.map(|options| options.tracer_config.only_top_call)
.unwrap_or(false);
let options = options.unwrap_or_default();

let mut connection = self.state.acquire_connection().await?;
let block_args = self
Expand Down Expand Up @@ -264,7 +277,7 @@ impl DebugNamespace {

// We don't need properly trace if we only need top call
let tracing_params = OneshotTracingParams {
trace_calls: !only_top_call,
trace_calls: !options.tracer_config.only_top_call,
};

let connection = self.state.acquire_connection().await?;
Expand Down
27 changes: 9 additions & 18 deletions core/node/api_server/src/web3/tests/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
use zksync_multivm::interface::{Call, TransactionExecutionResult};
use zksync_types::{
api::{
CallTracerBlockResult, CallTracerConfig, CallTracerResult, SupportedTracers, TracerConfig,
},
api::{CallTracerConfig, SupportedTracers, TracerConfig},
BOOTLOADER_ADDRESS,
};
use zksync_web3_decl::{
Expand Down Expand Up @@ -63,11 +61,9 @@ impl HttpTest for TraceBlockTest {
let block_traces = match block_id {
api::BlockId::Number(number) => client.trace_block_by_number(number, None).await?,
api::BlockId::Hash(hash) => client.trace_block_by_hash(hash, None).await?,
};
}
.unwrap_default();

let CallTracerBlockResult::CallTrace(block_traces) = block_traces else {
unreachable!()
};
assert_eq!(block_traces.len(), tx_results.len()); // equals to the number of transactions in the block
for (trace, tx_result) in block_traces.iter().zip(&tx_results) {
let result = &trace.result;
Expand Down Expand Up @@ -140,11 +136,8 @@ impl HttpTest for TraceBlockFlatTest {
},
}),
)
.await?;

let CallTracerBlockResult::FlatCallTrace(block_traces) = &block_traces else {
unreachable!()
};
.await?
.unwrap_flatten();

// A transaction with 2 nested calls will convert into 3 Flattened calls.
// Also in this test, all tx have the same # of nested calls
Expand All @@ -155,10 +148,10 @@ impl HttpTest for TraceBlockFlatTest {

// First tx has 2 nested calls, thus 2 sub-traces
assert_eq!(block_traces[0].subtraces, 2);
assert_eq!(block_traces[0].traceaddress, [0]);
assert_eq!(block_traces[0].trace_address, [0]);
// Second flat-call (fist nested call) do not have nested calls
assert_eq!(block_traces[1].subtraces, 0);
assert_eq!(block_traces[1].traceaddress, [0, 0]);
assert_eq!(block_traces[1].trace_address, [0, 0]);

let top_level_call_indexes = [0, 3, 6];
let top_level_traces = top_level_call_indexes
Expand Down Expand Up @@ -231,13 +224,11 @@ impl HttpTest for TraceTransactionTest {
.map(|call| DebugNamespace::map_default_call(call.clone(), false))
.collect();

let CallTracerResult::CallTrace(result) = client
let result = client
.trace_transaction(tx_results[0].hash, None)
.await?
.context("no transaction traces")?
else {
unreachable!()
};
.unwrap_default();
assert_eq!(result.from, Address::zero());
assert_eq!(result.to, BOOTLOADER_ADDRESS);
assert_eq!(result.gas, tx_results[0].transaction.gas_limit());
Expand Down
Loading

0 comments on commit 618bf1a

Please sign in to comment.