Skip to content

Commit

Permalink
create dry run helper for sui transactional test runner
Browse files Browse the repository at this point in the history
  • Loading branch information
jordanjennings-mysten committed Jan 18, 2025
1 parent 4d7b082 commit bb97d62
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 28 deletions.
2 changes: 2 additions & 0 deletions crates/sui-transactional-test-runner/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ pub struct ProgrammableTransactionCommand {
pub gas_payment: Option<FakeID>,
#[clap(long = "dev-inspect")]
pub dev_inspect: bool,
#[clap(long = "dry-run")]
pub dry_run: bool,
#[clap(
long = "inputs",
value_parser = ParsedValue::<SuiExtraValueArgs>::parse,
Expand Down
29 changes: 27 additions & 2 deletions crates/sui-transactional-test-runner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use sui_core::authority::authority_per_epoch_store::CertLockGuard;
use sui_core::authority::authority_test_utils::send_and_confirm_transaction_with_execution_error;
use sui_core::authority::AuthorityState;
use sui_json_rpc::authority_state::StateRead;
use sui_json_rpc_types::DevInspectResults;
use sui_json_rpc_types::EventFilter;
use sui_json_rpc_types::{DevInspectResults, DryRunTransactionBlockResponse};
use sui_storage::key_value_store::TransactionKeyValueStore;
use sui_types::base_types::ObjectID;
use sui_types::base_types::SuiAddress;
Expand All @@ -45,10 +45,10 @@ use sui_types::storage::ObjectStore;
use sui_types::storage::ReadStore;
use sui_types::sui_system_state::epoch_start_sui_system_state::EpochStartSystemStateTrait;
use sui_types::sui_system_state::SuiSystemStateTrait;
use sui_types::transaction::InputObjects;
use sui_types::transaction::Transaction;
use sui_types::transaction::TransactionDataAPI;
use sui_types::transaction::TransactionKind;
use sui_types::transaction::{InputObjects, TransactionData};
use test_adapter::{SuiTestAdapter, PRE_COMPILED};

#[cfg_attr(not(msim), tokio::main)]
Expand Down Expand Up @@ -99,6 +99,12 @@ pub trait TransactionalAdapter: Send + Sync + ReadStore {
amount: u64,
) -> anyhow::Result<TransactionEffects>;

async fn dry_run_transaction_block(
&self,
transaction_block: TransactionData,
transaction_digest: TransactionDigest,
) -> SuiResult<DryRunTransactionBlockResponse>;

async fn dev_inspect_transaction_block(
&self,
sender: SuiAddress,
Expand Down Expand Up @@ -172,6 +178,17 @@ impl TransactionalAdapter for ValidatorWithFullnode {
Ok((effects, error))
}

async fn dry_run_transaction_block(
&self,
transaction_block: TransactionData,
transaction_digest: TransactionDigest,
) -> SuiResult<DryRunTransactionBlockResponse> {
self.fullnode
.dry_exec_transaction(transaction_block, transaction_digest)
.await
.map(|result| result.0)
}

async fn dev_inspect_transaction_block(
&self,
sender: SuiAddress,
Expand Down Expand Up @@ -409,6 +426,14 @@ impl TransactionalAdapter for Simulacrum<StdRng, PersistedStore> {
unimplemented!("dev_inspect_transaction_block not supported in simulator mode")
}

async fn dry_run_transaction_block(
&self,
_transaction_block: TransactionData,
_transaction_digest: TransactionDigest,
) -> SuiResult<DryRunTransactionBlockResponse> {
unimplemented!("dry_run_transaction_block not supported in simulator mode")
}

async fn query_tx_events_asc(
&self,
tx_digest: &TransactionDigest,
Expand Down
93 changes: 67 additions & 26 deletions crates/sui-transactional-test-runner/src/test_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ use sui_core::authority::AuthorityState;
use sui_framework::DEFAULT_FRAMEWORK_PATH;
use sui_graphql_rpc::test_infra::cluster::{RetentionConfig, SnapshotLagConfig};
use sui_json_rpc_api::QUERY_MAX_RESULT_LIMIT;
use sui_json_rpc_types::{DevInspectResults, SuiExecutionStatus, SuiTransactionBlockEffectsAPI};
use sui_json_rpc_types::{
DevInspectResults, DryRunTransactionBlockResponse, SuiExecutionStatus,
SuiTransactionBlockEffects, SuiTransactionBlockEffectsAPI, SuiTransactionBlockEvents,
};
use sui_protocol_config::{Chain, ProtocolConfig};
use sui_storage::{
key_value_store::TransactionKeyValueStore, key_value_store_metrics::KeyValueStoreMetrics,
Expand Down Expand Up @@ -825,12 +828,17 @@ impl<'a> MoveTestAdapter<'a> for SuiTestAdapter {
gas_price,
gas_payment,
dev_inspect,
dry_run,
inputs,
}) => {
if dev_inspect && self.is_simulator() {
bail!("Dev inspect is not supported on simulator mode");
}

if dry_run && dev_inspect {
bail!("Cannot set both dev-inspect and dry-run");
}

let inputs = self.compiled_state().resolve_args(inputs)?;
let inputs: Vec<CallArg> = inputs
.into_iter()
Expand Down Expand Up @@ -866,7 +874,8 @@ impl<'a> MoveTestAdapter<'a> for SuiTestAdapter {
)
})
.collect::<anyhow::Result<Vec<Command>>>()?;
let summary = if !dev_inspect {

let summary = if !dev_inspect && !dry_run {
let gas_budget = gas_budget.unwrap_or(DEFAULT_GAS_BUDGET);
let gas_price = gas_price.unwrap_or(self.gas_price);
let transaction = self.sign_sponsor_txn(
Expand All @@ -885,6 +894,16 @@ impl<'a> MoveTestAdapter<'a> for SuiTestAdapter {
},
);
self.execute_txn(transaction).await?
} else if dry_run {
let sender_address = self.get_sender(sender).address;
let transaction = TransactionData::new_programmable(
sender_address,
vec![],
ProgrammableTransaction { inputs, commands },
0,
0,
);
self.dry_run(transaction).await?
} else {
assert!(
gas_budget.is_none(),
Expand Down Expand Up @@ -1640,6 +1659,19 @@ impl<'a> SuiTestAdapter {
}
}

async fn dry_run(&mut self, transaction: TransactionData) -> anyhow::Result<TxnSummary> {
let digest = transaction.digest();
let results = self
.executor
.dry_run_transaction_block(transaction, digest)
.await?;
let DryRunTransactionBlockResponse {
effects, events, ..
} = results;

self.tx_summary_from_effects(effects, events)
}

async fn dev_inspect(
&mut self,
sender: SuiAddress,
Expand All @@ -1653,6 +1685,21 @@ impl<'a> SuiTestAdapter {
let DevInspectResults {
effects, events, ..
} = results;

self.tx_summary_from_effects(effects, events)
}

fn tx_summary_from_effects(
&mut self,
effects: SuiTransactionBlockEffects,
events: SuiTransactionBlockEvents,
) -> anyhow::Result<TxnSummary> {
if let SuiExecutionStatus::Failure { error } = effects.status() {
return Err(anyhow::anyhow!(self.stabilize_str(format!(
"Transaction Effects Status: {error}\nExecution Error: {error}",
))));
}

let mut created_ids: Vec<_> = effects.created().iter().map(|o| o.object_id()).collect();
let mut mutated_ids: Vec<_> = effects.mutated().iter().map(|o| o.object_id()).collect();
let mut unwrapped_ids: Vec<_> = effects.unwrapped().iter().map(|o| o.object_id()).collect();
Expand Down Expand Up @@ -1689,30 +1736,24 @@ impl<'a> SuiTestAdapter {
unwrapped_then_deleted_ids.sort_by_key(|id| self.real_to_fake_object_id(id));
wrapped_ids.sort_by_key(|id| self.real_to_fake_object_id(id));

match effects.status() {
SuiExecutionStatus::Success { .. } => {
let events = events
.data
.into_iter()
.map(|sui_event| sui_event.into())
.collect();
Ok(TxnSummary {
events,
gas_summary: gas_summary.clone(),
created: created_ids,
mutated: mutated_ids,
unwrapped: unwrapped_ids,
deleted: deleted_ids,
unwrapped_then_deleted: unwrapped_then_deleted_ids,
wrapped: wrapped_ids,
// TODO: Properly propagate unchanged shared objects in dev_inspect.
unchanged_shared: vec![],
})
}
SuiExecutionStatus::Failure { error } => Err(anyhow::anyhow!(self.stabilize_str(
format!("Transaction Effects Status: {error}\nExecution Error: {error}",)
))),
}
let events = events
.data
.into_iter()
.map(|sui_event| sui_event.into())
.collect();

Ok(TxnSummary {
events,
gas_summary: gas_summary.clone(),
created: created_ids,
mutated: mutated_ids,
unwrapped: unwrapped_ids,
deleted: deleted_ids,
unwrapped_then_deleted: unwrapped_then_deleted_ids,
wrapped: wrapped_ids,
// TODO: Properly propagate unchanged shared objects in dev_inspect.
unchanged_shared: vec![],
})
}

fn get_object(&self, id: &ObjectID, version: Option<SequenceNumber>) -> anyhow::Result<Object> {
Expand Down

0 comments on commit bb97d62

Please sign in to comment.