Skip to main content

sui_cluster_test/test_case/
fullnode_execute_transaction_test.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{TestCaseImpl, TestContext};
5use async_trait::async_trait;
6use sui_types::effects::TransactionEffectsAPI;
7use tracing::info;
8
9pub struct FullNodeExecuteTransactionTest;
10
11#[async_trait]
12impl TestCaseImpl for FullNodeExecuteTransactionTest {
13    fn name(&self) -> &'static str {
14        "FullNodeExecuteTransaction"
15    }
16
17    fn description(&self) -> &'static str {
18        "Test executing transactions via the gRPC TransactionExecutionService"
19    }
20
21    async fn run(&self, ctx: &mut TestContext) -> Result<(), anyhow::Error> {
22        let txn_count = 2;
23        let mut txns = ctx.make_transactions(txn_count).await;
24        assert!(
25            txns.len() >= txn_count,
26            "Expect at least {} txns, but only got {}. Do we generate enough gas objects during genesis?",
27            txn_count,
28            txns.len(),
29        );
30
31        // This test intentionally drives execution directly rather than through
32        // the shared `sign_and_execute` helper, because its whole purpose is to
33        // exercise both gRPC execution paths.
34
35        // Path 1: immediate execution (`TransactionExecutionService`). The
36        // response carries the effects immediately, before checkpointing. We
37        // then wait for ledger/checkpoint visibility and retrieve the tx.
38        info!("Test immediate execute_transaction");
39        let txn = txns.swap_remove(0);
40        let txn_digest = *txn.digest();
41
42        let mut client = ctx.get_grpc_client();
43        let response = client.execute_transaction(&txn).await?;
44        assert!(
45            response.effects.status().is_ok(),
46            "Failed to execute transaction {:?}: {:?}",
47            txn_digest,
48            response.effects.status(),
49        );
50
51        // Wait for checkpoint visibility, then retrieve the transaction from the
52        // ledger (`LedgerService`).
53        ctx.wait_for_txns(&[txn_digest]).await;
54        let fetched = client.get_transaction(&txn_digest).await?;
55        assert!(
56            fetched.effects.status().is_ok(),
57            "Fetched transaction {:?} has non-success effects",
58            txn_digest,
59        );
60
61        // Path 2: execute-and-wait-for-checkpoint helper. The returned result
62        // must carry a checkpoint.
63        info!("Test execute_transaction_and_wait_for_checkpoint");
64        let txn = txns.swap_remove(0);
65        let txn_digest = *txn.digest();
66
67        let response = client
68            .execute_transaction_and_wait_for_checkpoint(&txn)
69            .await?;
70        assert!(
71            response.effects.status().is_ok(),
72            "Failed to execute transaction {:?}: {:?}",
73            txn_digest,
74            response.effects.status(),
75        );
76        assert!(
77            response.checkpoint.is_some(),
78            "execute_transaction_and_wait_for_checkpoint should return a checkpoint for {:?}",
79            txn_digest,
80        );
81
82        Ok(())
83    }
84}