sui_core/
test_utils.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use fastcrypto::traits::KeyPair;
5use move_core_types::{account_address::AccountAddress, ident_str};
6use shared_crypto::intent::{Intent, IntentScope};
7use std::sync::Arc;
8use std::time::Duration;
9use sui_config::genesis::Genesis;
10use sui_macros::nondeterministic;
11use sui_types::base_types::{FullObjectRef, ObjectID, random_object_ref};
12use sui_types::crypto::AuthorityKeyPair;
13use sui_types::crypto::{AccountKeyPair, Signer};
14use sui_types::effects::TestEffectsBuilder;
15use sui_types::transaction::ObjectArg;
16use sui_types::transaction::{
17    CallArg, TEST_ONLY_GAS_UNIT_FOR_TRANSFER, Transaction, TransactionData,
18};
19use sui_types::utils::create_fake_transaction;
20use sui_types::utils::to_sender_signed_transaction;
21use sui_types::{
22    base_types::{AuthorityName, ExecutionDigests, ObjectRef, SuiAddress, TransactionDigest},
23    committee::Committee,
24    crypto::{AuthoritySignInfo, AuthoritySignature},
25    message_envelope::Message,
26    transaction::CertifiedTransaction,
27};
28use tokio::time::timeout;
29use tracing::{info, warn};
30
31use crate::authority::AuthorityState;
32
33// note: clippy is confused about this being dead - it appears to only be used in cfg(test), but
34// adding #[cfg(test)] causes other targets to fail
35#[allow(dead_code)]
36pub(crate) fn init_state_parameters_from_rng<R>(rng: &mut R) -> (Genesis, AuthorityKeyPair)
37where
38    R: rand::CryptoRng + rand::RngCore,
39{
40    let dir = nondeterministic!(tempfile::TempDir::new().unwrap());
41    let network_config = sui_swarm_config::network_config_builder::ConfigBuilder::new(&dir)
42        .rng(rng)
43        .build();
44    let genesis = network_config.genesis;
45    let authority_key = network_config.validator_configs[0]
46        .protocol_key_pair()
47        .copy();
48
49    (genesis, authority_key)
50}
51
52pub async fn wait_for_tx(digest: TransactionDigest, state: Arc<AuthorityState>, delay: Duration) {
53    match timeout(
54        delay,
55        state
56            .get_transaction_cache_reader()
57            .notify_read_executed_effects("", &[digest]),
58    )
59    .await
60    {
61        Ok(_) => {
62            info!(?digest, "digest found");
63        }
64        Err(e) => {
65            warn!(?digest, "digest not found!");
66            panic!("timed out waiting for effects of digest! {e}");
67        }
68    }
69}
70
71pub fn create_fake_cert_and_effect_digest<'a>(
72    signers: impl Iterator<
73        Item = (
74            &'a AuthorityName,
75            &'a (dyn Signer<AuthoritySignature> + Send + Sync),
76        ),
77    >,
78    committee: &Committee,
79) -> (ExecutionDigests, CertifiedTransaction) {
80    let transaction = create_fake_transaction();
81    let cert = CertifiedTransaction::new(
82        transaction.data().clone(),
83        signers
84            .map(|(name, signer)| {
85                AuthoritySignInfo::new(
86                    committee.epoch,
87                    transaction.data(),
88                    Intent::sui_app(IntentScope::SenderSignedTransaction),
89                    *name,
90                    signer,
91                )
92            })
93            .collect(),
94        committee,
95    )
96    .unwrap();
97    let effects = TestEffectsBuilder::new(transaction.data()).build();
98    (
99        ExecutionDigests::new(*transaction.digest(), effects.digest()),
100        cert,
101    )
102}
103
104pub fn make_transfer_sui_transaction(
105    gas_object: ObjectRef,
106    recipient: SuiAddress,
107    amount: Option<u64>,
108    sender: SuiAddress,
109    keypair: &AccountKeyPair,
110    gas_price: u64,
111) -> Transaction {
112    let data = TransactionData::new_transfer_sui(
113        recipient,
114        sender,
115        amount,
116        gas_object,
117        gas_price * TEST_ONLY_GAS_UNIT_FOR_TRANSFER,
118        gas_price,
119    );
120    to_sender_signed_transaction(data, keypair)
121}
122
123pub fn make_pay_sui_transaction(
124    gas_object: ObjectRef,
125    coins: Vec<ObjectRef>,
126    recipients: Vec<SuiAddress>,
127    amounts: Vec<u64>,
128    sender: SuiAddress,
129    keypair: &AccountKeyPair,
130    gas_price: u64,
131    gas_budget: u64,
132) -> Transaction {
133    let data = TransactionData::new_pay_sui(
134        sender, coins, recipients, amounts, gas_object, gas_budget, gas_price,
135    )
136    .unwrap();
137    to_sender_signed_transaction(data, keypair)
138}
139
140pub fn make_transfer_object_transaction(
141    object_ref: ObjectRef,
142    gas_object: ObjectRef,
143    sender: SuiAddress,
144    keypair: &AccountKeyPair,
145    recipient: SuiAddress,
146    gas_price: u64,
147) -> Transaction {
148    let data = TransactionData::new_transfer(
149        recipient,
150        FullObjectRef::from_fastpath_ref(object_ref),
151        sender,
152        gas_object,
153        gas_price * TEST_ONLY_GAS_UNIT_FOR_TRANSFER * 10,
154        gas_price,
155    );
156    to_sender_signed_transaction(data, keypair)
157}
158
159pub fn make_transfer_object_move_transaction(
160    src: SuiAddress,
161    keypair: &AccountKeyPair,
162    dest: SuiAddress,
163    object_ref: ObjectRef,
164    framework_obj_id: ObjectID,
165    gas_object_ref: ObjectRef,
166    gas_budget_in_units: u64,
167    gas_price: u64,
168) -> Transaction {
169    let args = vec![
170        CallArg::Object(ObjectArg::ImmOrOwnedObject(object_ref)),
171        CallArg::Pure(bcs::to_bytes(&AccountAddress::from(dest)).unwrap()),
172    ];
173
174    to_sender_signed_transaction(
175        TransactionData::new_move_call(
176            src,
177            framework_obj_id,
178            ident_str!("object_basics").to_owned(),
179            ident_str!("transfer").to_owned(),
180            Vec::new(),
181            gas_object_ref,
182            args,
183            gas_budget_in_units * gas_price,
184            gas_price,
185        )
186        .unwrap(),
187        keypair,
188    )
189}
190
191/// Make a dummy tx that uses random object refs.
192pub fn make_dummy_tx(
193    receiver: SuiAddress,
194    sender: SuiAddress,
195    sender_sec: &AccountKeyPair,
196) -> Transaction {
197    Transaction::from_data_and_signer(
198        TransactionData::new_transfer(
199            receiver,
200            FullObjectRef::from_fastpath_ref(random_object_ref()),
201            sender,
202            random_object_ref(),
203            TEST_ONLY_GAS_UNIT_FOR_TRANSFER * 10,
204            10,
205        ),
206        vec![sender_sec],
207    )
208}