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