Skip to content

Commit

Permalink
Various fixes and work towards Rust client support
Browse files Browse the repository at this point in the history
  • Loading branch information
Dentosal committed Dec 12, 2024
1 parent 6ebe050 commit cd0704a
Show file tree
Hide file tree
Showing 14 changed files with 267 additions and 28 deletions.
20 changes: 10 additions & 10 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion benches/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ impl TryFrom<VmBench> for VmBenchPrepared {
}
let storage_diff = vm.storage_diff();
let mut vm = vm.remove_recording();
let mut diff = start_vm.diff(&vm);
let mut diff = start_vm.rollback_to(&vm);
diff += storage_diff;
let diff: diff::Diff<diff::InitialVmState> = diff.into();
vm.reset_vm_state(&diff);
Expand Down
2 changes: 1 addition & 1 deletion bin/fuel-core/src/cli/run/graphql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub struct QueryCosts {
)]
pub dry_run: usize,

/// Query costs for generating execution trace for a block.
/// Query costs for generating execution trace for a block.®
#[clap(
long = "query-cost-execution-trace-block",
default_value = DEFAULT_QUERY_COSTS.execution_trace_block.to_string(),
Expand Down
31 changes: 25 additions & 6 deletions crates/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,19 @@ use fuel_core_types::{
fuel_asm::{
Instruction,
Word,
},
fuel_tx::{
}, fuel_tx::{
BlobId,
Bytes32,
ConsensusParameters,
Receipt,
Transaction,
TxId,
},
fuel_types::{
}, fuel_types::{
self,
canonical::Serialize,
BlockHeight,
Nonce,
},
services::executor::TransactionExecutionStatus,
}, fuel_vm::interpreter::trace::Trigger, services::executor::TransactionExecutionStatus
};
#[cfg(feature = "subscriptions")]
use futures::{
Expand Down Expand Up @@ -506,6 +503,28 @@ impl FuelClient {
.collect()
}

/// Exectuion trace for a block

Check warning on line 506 in crates/client/src/client.rs

View workflow job for this annotation

GitHub Actions / find-typos

"Exectuion" should be "Execution".
pub async fn execution_trace_block(
&self,
height: &BlockHeight,
trigger: Trigger
) -> io::Result<Vec<TransactionExecutionStatus>> {
let query: Operation<
schema::execution_trace::ExectionTraceBlock,

Check warning on line 513 in crates/client/src/client.rs

View workflow job for this annotation

GitHub Actions / find-typos

"Exection" should be "Execution".
schema::execution_trace::ExectionTraceBlockArgs,

Check warning on line 514 in crates/client/src/client.rs

View workflow job for this annotation

GitHub Actions / find-typos

"Exection" should be "Execution".
> = schema::execution_trace::ExectionTraceBlock::build(

Check warning on line 515 in crates/client/src/client.rs

View workflow job for this annotation

GitHub Actions / find-typos

"Exection" should be "Execution".
schema::execution_trace::ExectionTraceBlockArgs {

Check warning on line 516 in crates/client/src/client.rs

View workflow job for this annotation

GitHub Actions / find-typos

"Exection" should be "Execution".
height: (*height).into(),
trigger: trigger.into(),
},
);
let tx_statuses = self.query(query).await.map(|r| r.execution_trace_block)?;
tx_statuses
.into_iter()
.map(|tx_status| tx_status.try_into().map_err(Into::into))
.collect()
}

/// Estimate predicates for the transaction
pub async fn estimate_predicates(&self, tx: &mut Transaction) -> io::Result<()> {
let serialized_tx = tx.to_bytes();
Expand Down
1 change: 1 addition & 0 deletions crates/client/src/client/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub mod chain;
pub mod coins;
pub mod contract;
pub mod da_compressed;
pub mod execution_trace;
pub mod message;
pub mod node_info;
pub mod upgrades;
Expand Down
207 changes: 207 additions & 0 deletions crates/client/src/client/schema/execution_trace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
use crate::client::{
schema::{
schema,
tx::transparent_receipt::Receipt,
Address,
ConversionError,
TransactionId,
U32,
U64,
},
PageDirection,
PaginationRequest,
};
use fuel_core_types::{
fuel_tx, fuel_vm::interpreter::trace::Trigger, services::executor::{
TransactionExecutionResult,
TransactionExecutionStatus,
}
};
use std::convert::{
TryFrom,
TryInto,
};

use super::tx::{
ProgramState,
};

#[allow(clippy::enum_variant_names)]
#[derive(cynic::InlineFragments, Clone, Debug)]
#[cynic(schema_path = "./assets/schema.sdl")]
pub enum TraceTransactionStatus {
SuccessStatus(TraceSuccessStatus),
FailureStatus(TraceFailureStatus),
#[cynic(fallback)]
Unknown,
}

impl TryFrom<TraceTransactionStatus> for TransactionExecutionResult {
type Error = ConversionError;

fn try_from(status: TraceTransactionStatus) -> Result<Self, Self::Error> {
Ok(match status {
TraceTransactionStatus::SuccessStatus(s) => {
let receipts = s
.receipts
.into_iter()
.map(|receipt| receipt.try_into())
.collect::<Result<Vec<fuel_tx::Receipt>, _>>()?;
TransactionExecutionResult::Success {
result: s.program_state.map(TryInto::try_into).transpose()?,
receipts,
execution_trace: Vec::new(), // Not produced by dry-run
total_gas: s.total_gas.0,
total_fee: s.total_fee.0,
}
}
TraceTransactionStatus::FailureStatus(s) => {
let receipts = s
.receipts
.into_iter()
.map(|receipt| receipt.try_into())
.collect::<Result<Vec<fuel_tx::Receipt>, _>>()?;
TransactionExecutionResult::Failed {
result: s.program_state.map(TryInto::try_into).transpose()?,
receipts,
execution_trace: Vec::new(), // Not produced by dry-run
total_gas: s.total_gas.0,
total_fee: s.total_fee.0,
}
}
TraceTransactionStatus::Unknown => {
return Err(Self::Error::UnknownVariant("ExecutionTraceTxStatus"))
}
})
}
}

#[derive(cynic::QueryFragment, Clone, Debug)]
#[cynic(schema_path = "./assets/schema.sdl")]
pub struct TraceSuccessStatus {
pub program_state: Option<ProgramState>,
pub receipts: Vec<Receipt>,
pub total_gas: U64,
pub total_fee: U64,
}

#[derive(cynic::QueryFragment, Clone, Debug)]
#[cynic(schema_path = "./assets/schema.sdl")]
pub struct TraceFailureStatus {
pub program_state: Option<ProgramState>,
pub receipts: Vec<Receipt>,
pub total_gas: U64,
pub total_fee: U64,
}

#[derive(cynic::QueryFragment, Clone, Debug)]
#[cynic(schema_path = "./assets/schema.sdl")]
pub struct TraceTransactionExecutionStatus {
pub id: TransactionId,
pub status: TraceTransactionStatus,
}

impl TryFrom<TraceTransactionExecutionStatus> for TransactionExecutionStatus {
type Error = ConversionError;

fn try_from(schema: TraceTransactionExecutionStatus) -> Result<Self, Self::Error> {
let id = schema.id.into();
let status = schema.status.try_into()?;

Ok(TransactionExecutionStatus { id, result: status })
}
}

#[derive(cynic::QueryVariables, Debug)]
pub struct TransactionsByOwnerConnectionArgs {
/// Select transactions based on related `owner`s
pub owner: Address,
/// Skip until cursor (forward pagination)
pub after: Option<String>,
/// Skip until cursor (backward pagination)
pub before: Option<String>,
/// Retrieve the first n transactions in order (forward pagination)
pub first: Option<i32>,
/// Retrieve the last n transactions in order (backward pagination).
/// Can't be used at the same time as `first`.
pub last: Option<i32>,
}

impl From<(Address, PaginationRequest<String>)> for TransactionsByOwnerConnectionArgs {
fn from(r: (Address, PaginationRequest<String>)) -> Self {
match r.1.direction {
PageDirection::Forward => TransactionsByOwnerConnectionArgs {
owner: r.0,
after: r.1.cursor,
before: None,
first: Some(r.1.results),
last: None,
},
PageDirection::Backward => TransactionsByOwnerConnectionArgs {
owner: r.0,
after: None,
before: r.1.cursor,
first: None,
last: Some(r.1.results),
},
}
}
}

// mutations


/// When to record a trace frames during execution
#[derive(cynic::Enum, Debug, Copy, Clone, Eq, PartialEq)]
#[cynic(
schema_path = "./assets/schema.sdl",
graphql_type = "TraceTrigger",
)]
pub enum TraceTrigger {
/// After each instruction
OnInstruction,
/// After an instruction has created a receipt
OnReceipt,
}
impl From<Trigger> for TraceTrigger {
fn from(value: Trigger) -> Self {
match value {
Trigger::OnInstruction => TraceTrigger::OnInstruction,
Trigger::OnReceipt => TraceTrigger::OnReceipt,
}
}
}

#[derive(cynic::QueryVariables, Debug)]
pub struct ExectionTraceBlockArgs {

Check warning on line 176 in crates/client/src/client/schema/execution_trace.rs

View workflow job for this annotation

GitHub Actions / find-typos

"Exection" should be "Execution".
pub height: U32,
pub trigger: TraceTrigger,
}

/// Retrieves the transaction in opaque form
#[derive(cynic::QueryFragment, Clone, Debug)]
#[cynic(
schema_path = "./assets/schema.sdl",
graphql_type = "Mutation",
variables = "ExectionTraceBlockArgs"

Check warning on line 186 in crates/client/src/client/schema/execution_trace.rs

View workflow job for this annotation

GitHub Actions / find-typos

"Exection" should be "Execution".
)]
pub struct ExectionTraceBlock {

Check warning on line 188 in crates/client/src/client/schema/execution_trace.rs

View workflow job for this annotation

GitHub Actions / find-typos

"Exection" should be "Execution".
#[arguments(height: $height, trigger: $trigger)]
pub execution_trace_block: Vec<TraceTransactionExecutionStatus>,
}

#[cfg(test)]
pub mod tests {
use super::*;
use fuel_core_types::fuel_types::BlockHeight;

#[test]
fn execution_trace_block_tx_gql_output() {
use cynic::MutationBuilder;
let query = ExectionTraceBlock::build(ExectionTraceBlockArgs {

Check warning on line 201 in crates/client/src/client/schema/execution_trace.rs

View workflow job for this annotation

GitHub Actions / find-typos

"Exection" should be "Execution".

Check warning on line 201 in crates/client/src/client/schema/execution_trace.rs

View workflow job for this annotation

GitHub Actions / find-typos

"Exection" should be "Execution".
height: BlockHeight::new(1234).into(),
trigger: TraceTrigger::OnReceipt,
});
insta::assert_snapshot!(query.query)
}
}
Loading

0 comments on commit cd0704a

Please sign in to comment.