diff --git a/crates/iroha/tests/queries/mod.rs b/crates/iroha/tests/queries/mod.rs index bb7c70ac7a..f6e2e3db0d 100644 --- a/crates/iroha/tests/queries/mod.rs +++ b/crates/iroha/tests/queries/mod.rs @@ -31,3 +31,44 @@ fn too_big_fetch_size_is_not_allowed() { )) )); } + +#[test] +fn find_blocks_reversed() -> eyre::Result<()> { + let (network, _rt) = NetworkBuilder::new().start_blocking()?; + let client = network.client(); + + client.submit_blocking(Register::domain(Domain::new("domain1".parse()?)))?; + + let blocks = client.query(FindBlocks).execute_all()?; + assert_eq!(blocks.len(), 2); + assert_eq!(blocks[1].header().prev_block_hash, None); + assert_eq!( + blocks[0].header().prev_block_hash, + Some(blocks[1].header().hash()) + ); + + Ok(()) +} + +#[test] +fn find_transactions_reversed() -> eyre::Result<()> { + let (network, _rt) = NetworkBuilder::new().start_blocking()?; + let client = network.client(); + + let register_domain = Register::domain(Domain::new("domain1".parse()?)); + client.submit_blocking(register_domain.clone())?; + + let txs = client.query(FindTransactions).execute_all()?; + + // check that latest transaction is register domain + let Executable::Instructions(instructions) = txs[0].transaction.value.instructions() else { + panic!("Expected instructions"); + }; + assert_eq!(instructions.len(), 1); + assert_eq!( + instructions[0], + InstructionBox::Register(register_domain.into()) + ); + + Ok(()) +} diff --git a/crates/iroha/tests/tx_history.rs b/crates/iroha/tests/tx_history.rs index adcafebcf4..73506a0581 100644 --- a/crates/iroha/tests/tx_history.rs +++ b/crates/iroha/tests/tx_history.rs @@ -51,16 +51,18 @@ fn client_has_rejected_and_accepted_txs_should_return_tx_history() -> Result<()> .execute_all()?; assert_eq!(transactions.len(), 50); - let mut prev_creation_time = core::time::Duration::from_millis(0); + let mut prev_creation_time = None; transactions .iter() .map(AsRef::as_ref) .map(AsRef::as_ref) .for_each(|tx| { assert_eq!(tx.authority(), &account_id); - //check sorted - assert!(tx.creation_time() >= prev_creation_time); - prev_creation_time = tx.creation_time(); + //check sorted descending + if let Some(prev_creation_time) = prev_creation_time { + assert!(tx.creation_time() <= prev_creation_time); + } + prev_creation_time = Some(tx.creation_time()); }); Ok(()) } diff --git a/crates/iroha_core/src/smartcontracts/isi/tx.rs b/crates/iroha_core/src/smartcontracts/isi/tx.rs index e12fd93073..f97999d84d 100644 --- a/crates/iroha_core/src/smartcontracts/isi/tx.rs +++ b/crates/iroha_core/src/smartcontracts/isi/tx.rs @@ -22,12 +22,14 @@ use nonzero_ext::nonzero; use super::*; use crate::smartcontracts::ValidQuery; +/// Iterates transactions of a block in reverse order pub(crate) struct BlockTransactionIter(Arc, usize); pub(crate) struct BlockTransactionRef(Arc, usize); impl BlockTransactionIter { fn new(block: Arc) -> Self { - Self(block, 0) + let n_transactions = block.transactions().len(); + Self(block, n_transactions) } } @@ -35,11 +37,9 @@ impl Iterator for BlockTransactionIter { type Item = BlockTransactionRef; fn next(&mut self) -> Option { - if self.1 < self.0.transactions().len() { - let res = Some(BlockTransactionRef(Arc::clone(&self.0), self.1)); - - self.1 += 1; - return res; + if self.1 != 0 { + self.1 -= 1; + return Some(BlockTransactionRef(Arc::clone(&self.0), self.1)); } None @@ -69,6 +69,7 @@ impl ValidQuery for FindTransactions { ) -> Result, QueryExecutionFail> { Ok(state_ro .all_blocks(nonzero!(1_usize)) + .rev() .flat_map(BlockTransactionIter::new) .map(|tx| TransactionQueryOutput { block_hash: tx.block_hash(),