1use core::default::Default;
7
8use fastcrypto::{hash::MultisetHash, traits::KeyPair};
9use iota_types::{
10 crypto::{AccountKeyPair, AuthorityKeyPair},
11 messages_consensus::ConsensusTransaction,
12 utils::to_sender_signed_transaction,
13};
14
15use super::{test_authority_builder::TestAuthorityBuilder, *};
16use crate::{checkpoints::CheckpointServiceNoop, consensus_handler::SequencedConsensusTransaction};
17
18pub async fn send_and_confirm_transaction(
19 authority: &AuthorityState,
20 transaction: Transaction,
21) -> Result<(CertifiedTransaction, SignedTransactionEffects), IotaError> {
22 send_and_confirm_transaction_(
23 authority,
24 None, transaction,
26 false, )
28 .await
29}
30pub async fn send_and_confirm_transaction_(
31 authority: &AuthorityState,
32 fullnode: Option<&AuthorityState>,
33 transaction: Transaction,
34 with_shared: bool, ) -> Result<(CertifiedTransaction, SignedTransactionEffects), IotaError> {
36 let (txn, effects, _execution_error_opt) = send_and_confirm_transaction_with_execution_error(
37 authority,
38 fullnode,
39 transaction,
40 with_shared,
41 true,
42 )
43 .await?;
44 Ok((txn, effects))
45}
46
47pub async fn certify_transaction(
48 authority: &AuthorityState,
49 transaction: Transaction,
50) -> Result<VerifiedCertificate, IotaError> {
51 let epoch_store = authority.load_epoch_store_one_call_per_task();
53 transaction.validity_check(epoch_store.protocol_config(), epoch_store.epoch())?;
55 let transaction = epoch_store.verify_transaction(transaction).unwrap();
56
57 let response = authority
58 .handle_transaction(&epoch_store, transaction.clone())
59 .await?;
60 let vote = response.status.into_signed_for_testing();
61
62 let committee = authority.clone_committee_for_testing();
64 let certificate = CertifiedTransaction::new(transaction.into_message(), vec![vote], &committee)
65 .unwrap()
66 .try_into_verified_for_testing(&committee, &Default::default())
67 .unwrap();
68 Ok(certificate)
69}
70
71pub async fn execute_certificate_with_execution_error(
72 authority: &AuthorityState,
73 fullnode: Option<&AuthorityState>,
74 certificate: VerifiedCertificate,
75 with_shared: bool, fake_consensus: bool,
77) -> Result<
78 (
79 CertifiedTransaction,
80 SignedTransactionEffects,
81 Option<ExecutionError>,
82 ),
83 IotaError,
84> {
85 let state_acc =
90 GlobalStateHasher::new_for_tests(authority.get_global_state_hash_store().clone());
91 let mut state = state_acc.accumulate_cached_live_object_set_for_testing();
92
93 if with_shared {
94 if fake_consensus {
95 send_consensus(authority, &certificate).await;
96 } else {
97 authority
99 .epoch_store_for_testing()
100 .assign_shared_object_versions_for_tests(
101 authority.get_object_cache_reader().as_ref(),
102 &[VerifiedExecutableTransaction::new_from_certificate(
103 certificate.clone(),
104 )],
105 )?;
106 }
107 if let Some(fullnode) = fullnode {
108 fullnode
109 .epoch_store_for_testing()
110 .assign_shared_object_versions_for_tests(
111 fullnode.get_object_cache_reader().as_ref(),
112 &[VerifiedExecutableTransaction::new_from_certificate(
113 certificate.clone(),
114 )],
115 )?;
116 }
117 }
118
119 let (result, execution_error_opt) = authority.try_execute_for_test(&certificate)?;
124 let state_after = state_acc.accumulate_cached_live_object_set_for_testing();
125 let effects_acc = state_acc.accumulate_effects(&[result.inner().data().clone()]);
126 state.union(&effects_acc);
127
128 assert_eq!(state_after.digest(), state.digest());
129
130 if let Some(fullnode) = fullnode {
131 fullnode.try_execute_for_test(&certificate)?;
132 }
133 Ok((
134 certificate.into_inner(),
135 result.into_inner(),
136 execution_error_opt,
137 ))
138}
139
140pub async fn send_and_confirm_transaction_with_execution_error(
141 authority: &AuthorityState,
142 fullnode: Option<&AuthorityState>,
143 transaction: Transaction,
144 with_shared: bool, fake_consensus: bool, ) -> Result<
147 (
148 CertifiedTransaction,
149 SignedTransactionEffects,
150 Option<ExecutionError>,
151 ),
152 IotaError,
153> {
154 let certificate = certify_transaction(authority, transaction).await?;
155 execute_certificate_with_execution_error(
156 authority,
157 fullnode,
158 certificate,
159 with_shared,
160 fake_consensus,
161 )
162 .await
163}
164
165pub async fn init_state_validator_with_fullnode() -> (Arc<AuthorityState>, Arc<AuthorityState>) {
166 use iota_types::crypto::get_authority_key_pair;
167
168 let validator = TestAuthorityBuilder::new().build().await;
169 let fullnode_key_pair = get_authority_key_pair().1;
170 let fullnode = TestAuthorityBuilder::new()
171 .with_keypair(&fullnode_key_pair)
172 .build()
173 .await;
174 (validator, fullnode)
175}
176
177pub async fn init_state_with_committee(
178 genesis: &Genesis,
179 authority_key: &AuthorityKeyPair,
180) -> Arc<AuthorityState> {
181 TestAuthorityBuilder::new()
182 .with_genesis_and_keypair(genesis, authority_key)
183 .build()
184 .await
185}
186
187pub async fn init_state_with_ids<I: IntoIterator<Item = (IotaAddress, ObjectID)>>(
188 objects: I,
189) -> Arc<AuthorityState> {
190 let state = TestAuthorityBuilder::new().build().await;
191 for (address, object_id) in objects {
192 let obj = Object::with_id_owner_for_testing(object_id, address);
193 state.insert_genesis_object(obj).await;
195 }
196 state
197}
198
199pub async fn init_state_with_ids_and_versions<
200 I: IntoIterator<Item = (IotaAddress, ObjectID, SequenceNumber)>,
201>(
202 objects: I,
203) -> Arc<AuthorityState> {
204 let state = TestAuthorityBuilder::new().build().await;
205 for (address, object_id, version) in objects {
206 let obj =
207 Object::with_id_owner_version_for_testing(object_id, version, Owner::Address(address));
208 state.insert_genesis_object(obj).await;
209 }
210 state
211}
212
213pub async fn init_state_with_objects<I: IntoIterator<Item = Object>>(
214 objects: I,
215) -> Arc<AuthorityState> {
216 let dir = tempfile::TempDir::new().unwrap();
217 let network_config =
218 iota_swarm_config::network_config_builder::ConfigBuilder::new(&dir).build();
219 let genesis = network_config.genesis;
220 let keypair = network_config.validator_configs[0]
221 .authority_key_pair()
222 .copy();
223 init_state_with_objects_and_committee(objects, &genesis, &keypair).await
224}
225
226pub async fn init_state_with_objects_and_committee<I: IntoIterator<Item = Object>>(
227 objects: I,
228 genesis: &Genesis,
229 authority_key: &AuthorityKeyPair,
230) -> Arc<AuthorityState> {
231 let state = init_state_with_committee(genesis, authority_key).await;
232 for o in objects {
233 state.insert_genesis_object(o).await;
234 }
235 state
236}
237
238pub async fn init_state_with_object_id(
239 address: IotaAddress,
240 object: ObjectID,
241) -> Arc<AuthorityState> {
242 init_state_with_ids(std::iter::once((address, object))).await
243}
244
245pub async fn init_state_with_ids_and_expensive_checks<
246 I: IntoIterator<Item = (IotaAddress, ObjectID)>,
247>(
248 objects: I,
249 config: ExpensiveSafetyCheckConfig,
250) -> Arc<AuthorityState> {
251 let state = TestAuthorityBuilder::new()
252 .with_expensive_safety_checks(config)
253 .build()
254 .await;
255 for (address, object_id) in objects {
256 let obj = Object::with_id_owner_for_testing(object_id, address);
257 state.insert_genesis_object(obj).await;
259 }
260 state
261}
262
263pub fn init_transfer_transaction(
264 authority_state: &AuthorityState,
265 sender: IotaAddress,
266 secret: &AccountKeyPair,
267 recipient: IotaAddress,
268 object_ref: ObjectRef,
269 gas_object_ref: ObjectRef,
270 gas_budget: u64,
271 gas_price: u64,
272) -> VerifiedTransaction {
273 let data = TransactionData::new_transfer(
274 recipient,
275 object_ref,
276 sender,
277 gas_object_ref,
278 gas_budget,
279 gas_price,
280 );
281 let tx = to_sender_signed_transaction(data, secret);
282 authority_state
283 .epoch_store_for_testing()
284 .verify_transaction(tx)
285 .unwrap()
286}
287
288pub fn init_certified_transfer_transaction(
289 sender: IotaAddress,
290 secret: &AccountKeyPair,
291 recipient: IotaAddress,
292 object_ref: ObjectRef,
293 gas_object_ref: ObjectRef,
294 authority_state: &AuthorityState,
295) -> VerifiedCertificate {
296 let rgp = authority_state.reference_gas_price_for_testing().unwrap();
297 let transfer_transaction = init_transfer_transaction(
298 authority_state,
299 sender,
300 secret,
301 recipient,
302 object_ref,
303 gas_object_ref,
304 rgp * TEST_ONLY_GAS_UNIT_FOR_TRANSFER,
305 rgp,
306 );
307 init_certified_transaction(transfer_transaction.into(), authority_state)
308}
309
310pub fn init_certified_transaction(
311 transaction: Transaction,
312 authority_state: &AuthorityState,
313) -> VerifiedCertificate {
314 let epoch_store = authority_state.epoch_store_for_testing();
315 let transaction = epoch_store.verify_transaction(transaction).unwrap();
316
317 let vote = VerifiedSignedTransaction::new(
318 0,
319 transaction.clone(),
320 authority_state.name,
321 &*authority_state.secret,
322 );
323 CertifiedTransaction::new(
324 transaction.into_message(),
325 vec![vote.auth_sig().clone()],
326 epoch_store.committee(),
327 )
328 .unwrap()
329 .try_into_verified_for_testing(epoch_store.committee(), &Default::default())
330 .unwrap()
331}
332
333pub async fn certify_shared_obj_transaction_no_execution(
334 authority: &AuthorityState,
335 transaction: Transaction,
336) -> Result<VerifiedCertificate, IotaError> {
337 let epoch_store = authority.load_epoch_store_one_call_per_task();
338 let transaction = epoch_store.verify_transaction(transaction).unwrap();
339 let response = authority
340 .handle_transaction(&epoch_store, transaction.clone())
341 .await?;
342 let vote = response.status.into_signed_for_testing();
343
344 let committee = authority.clone_committee_for_testing();
346 let certificate =
347 CertifiedTransaction::new(transaction.into_message(), vec![vote.clone()], &committee)
348 .unwrap()
349 .try_into_verified_for_testing(&committee, &Default::default())
350 .unwrap();
351
352 send_consensus_no_execution(authority, &certificate).await;
353
354 Ok(certificate)
355}
356
357pub async fn enqueue_all_and_execute_all(
358 authority: &AuthorityState,
359 certificates: Vec<VerifiedCertificate>,
360) -> Result<Vec<TransactionEffects>, IotaError> {
361 authority.enqueue_certificates_for_execution(
362 certificates.clone(),
363 &authority.epoch_store_for_testing(),
364 );
365 let mut output = Vec::new();
366 for cert in certificates {
367 let effects = authority.notify_read_effects(&cert).await?;
368 output.push(effects);
369 }
370 Ok(output)
371}
372
373pub async fn execute_sequenced_certificate_to_effects(
374 authority: &AuthorityState,
375 certificate: VerifiedCertificate,
376) -> Result<(TransactionEffects, Option<ExecutionError>), IotaError> {
377 authority.enqueue_certificates_for_execution(
378 vec![certificate.clone()],
379 &authority.epoch_store_for_testing(),
380 );
381
382 let (result, execution_error_opt) = authority.try_execute_for_test(&certificate)?;
383 let effects = result.inner().data().clone();
384 Ok((effects, execution_error_opt))
385}
386
387pub async fn send_consensus(authority: &AuthorityState, cert: &VerifiedCertificate) {
388 let transaction = SequencedConsensusTransaction::new_test(
389 ConsensusTransaction::new_certificate_message(&authority.name, cert.clone().into_inner()),
390 );
391
392 let certs = authority
393 .epoch_store_for_testing()
394 .process_consensus_transactions_for_tests(
395 vec![transaction],
396 &Arc::new(CheckpointServiceNoop {}),
397 authority.get_object_cache_reader().as_ref(),
398 authority.get_transaction_cache_reader().as_ref(),
399 &authority.metrics,
400 true,
401 )
402 .await
403 .unwrap();
404
405 authority
406 .transaction_manager()
407 .enqueue(certs, &authority.epoch_store_for_testing());
408}
409
410pub async fn send_consensus_no_execution(authority: &AuthorityState, cert: &VerifiedCertificate) {
411 let transaction = SequencedConsensusTransaction::new_test(
412 ConsensusTransaction::new_certificate_message(&authority.name, cert.clone().into_inner()),
413 );
414
415 authority
419 .epoch_store_for_testing()
420 .process_consensus_transactions_for_tests(
421 vec![transaction],
422 &Arc::new(CheckpointServiceNoop {}),
423 authority.get_object_cache_reader().as_ref(),
424 authority.get_transaction_cache_reader().as_ref(),
425 &authority.metrics,
426 true,
427 )
428 .await
429 .unwrap();
430}
431
432pub async fn send_batch_consensus_no_execution(
433 authority: &AuthorityState,
434 certificates: &[VerifiedCertificate],
435 skip_consensus_commit_prologue_in_test: bool,
436) -> Vec<VerifiedExecutableTransaction> {
437 let transactions = certificates
438 .iter()
439 .map(|cert| {
440 SequencedConsensusTransaction::new_test(ConsensusTransaction::new_certificate_message(
441 &authority.name,
442 cert.clone().into_inner(),
443 ))
444 })
445 .collect();
446
447 authority
451 .epoch_store_for_testing()
452 .process_consensus_transactions_for_tests(
453 transactions,
454 &Arc::new(CheckpointServiceNoop {}),
455 authority.get_object_cache_reader().as_ref(),
456 authority.get_transaction_cache_reader().as_ref(),
457 &authority.metrics,
458 skip_consensus_commit_prologue_in_test,
459 )
460 .await
461 .unwrap()
462}