diff --git a/rust-libs/modules/gva/dbs-reader/src/txs_history.rs b/rust-libs/modules/gva/dbs-reader/src/txs_history.rs index e5cf71acd9ebd71d7b7ee17831d10258508dedfe..240e7c7aa8e2027b98173099c80950911df2a75d 100644 --- a/rust-libs/modules/gva/dbs-reader/src/txs_history.rs +++ b/rust-libs/modules/gva/dbs-reader/src/txs_history.rs @@ -49,11 +49,37 @@ impl FromStr for TxBcCursor { impl DbsReader { pub fn get_txs_history_bc_received( &self, + from: Option<u64>, page_info: PageInfo<TxBcCursor>, script_hash: Hash, + to: Option<u64>, ) -> KvResult<PagedData<VecDeque<GvaTxDbV1>>> { - let mut start_k = WalletHashWithBnV1Db::new(script_hash, BlockNumber(0)); - let mut end_k = WalletHashWithBnV1Db::new(script_hash, BlockNumber(u32::MAX)); + let mut start_k = WalletHashWithBnV1Db::new( + script_hash, + BlockNumber(if let Some(from) = from { + self.0 + .blocks_by_common_time() + .iter(U64BE(from).., |it| it) + .values() + .next_res()? + .unwrap_or(u32::MAX) + } else { + 0 + }), + ); + let mut end_k = WalletHashWithBnV1Db::new( + script_hash, + BlockNumber(if let Some(to) = to { + self.0 + .blocks_by_common_time() + .iter_rev(..U64BE(to), |it| it) + .values() + .next_res()? + .unwrap_or(0) + } else { + u32::MAX + }), + ); let first_cursor_opt = if page_info.not_all() { self.0 .txs_by_recipient() @@ -168,11 +194,37 @@ impl DbsReader { } pub fn get_txs_history_bc_sent( &self, + from: Option<u64>, page_info: PageInfo<TxBcCursor>, script_hash: Hash, + to: Option<u64>, ) -> KvResult<PagedData<VecDeque<GvaTxDbV1>>> { - let mut start_k = WalletHashWithBnV1Db::new(script_hash, BlockNumber(0)); - let mut end_k = WalletHashWithBnV1Db::new(script_hash, BlockNumber(u32::MAX)); + let mut start_k = WalletHashWithBnV1Db::new( + script_hash, + BlockNumber(if let Some(from) = from { + self.0 + .blocks_by_common_time() + .iter(U64BE(from).., |it| it) + .values() + .next_res()? + .unwrap_or(u32::MAX) + } else { + 0 + }), + ); + let mut end_k = WalletHashWithBnV1Db::new( + script_hash, + BlockNumber(if let Some(to) = to { + self.0 + .blocks_by_common_time() + .iter_rev(..U64BE(to), |it| it) + .values() + .next_res()? + .unwrap_or(0) + } else { + u32::MAX + }), + ); let first_cursor_opt = if page_info.not_all() { self.0 .txs_by_issuer() @@ -525,6 +577,7 @@ mod tests { WalletHashWithBnV1Db::new(s1_hash, BlockNumber(1)), btreeset![Hash::default(), Hash([1; 32]), Hash([2; 32]), Hash([3; 32])], )?; + gva_db.blocks_by_common_time_write().upsert(U64BE(1), 1)?; gva_db.txs_write().upsert( HashKeyV2(Hash([4; 32])), gen_tx(Hash([4; 32]), BlockNumber(2)), @@ -537,6 +590,34 @@ mod tests { WalletHashWithBnV1Db::new(s1_hash, BlockNumber(2)), btreeset![Hash([4; 32]), Hash([5; 32])], )?; + gva_db.blocks_by_common_time_write().upsert(U64BE(2), 2)?; + gva_db.txs_write().upsert( + HashKeyV2(Hash([6; 32])), + gen_tx(Hash([6; 32]), BlockNumber(3)), + )?; + gva_db.txs_by_recipient_write().upsert( + WalletHashWithBnV1Db::new(s1_hash, BlockNumber(3)), + btreeset![Hash([6; 32])], + )?; + gva_db.blocks_by_common_time_write().upsert(U64BE(3), 3)?; + gva_db.txs_write().upsert( + HashKeyV2(Hash([7; 32])), + gen_tx(Hash([7; 32]), BlockNumber(4)), + )?; + gva_db.txs_by_recipient_write().upsert( + WalletHashWithBnV1Db::new(s1_hash, BlockNumber(4)), + btreeset![Hash([7; 32])], + )?; + gva_db.blocks_by_common_time_write().upsert(U64BE(4), 4)?; + gva_db.txs_write().upsert( + HashKeyV2(Hash([8; 32])), + gen_tx(Hash([8; 32]), BlockNumber(5)), + )?; + gva_db.txs_by_recipient_write().upsert( + WalletHashWithBnV1Db::new(s1_hash, BlockNumber(5)), + btreeset![Hash([8; 32])], + )?; + gva_db.blocks_by_common_time_write().upsert(U64BE(5), 5)?; /*let received = db_reader.get_txs_history_bc_received( PageInfo { @@ -581,6 +662,7 @@ mod tests { assert!(!received.has_previous_page);*/ let received = db_reader.get_txs_history_bc_received( + None, PageInfo { order: false, limit_opt: None, @@ -590,6 +672,7 @@ mod tests { }), }, s1_hash, + None, )?; assert_eq!( received @@ -608,6 +691,27 @@ mod tests { assert!(!received.has_next_page); assert!(!received.has_previous_page); + let received = db_reader.get_txs_history_bc_received( + Some(2), + PageInfo { + order: true, + limit_opt: None, + pos: None, + }, + s1_hash, + Some(5), + )?; + assert_eq!( + received + .data + .into_iter() + .map(|tx_db| tx_db.tx.get_hash()) + .collect::<Vec<_>>(), + vec![Hash([4; 32]), Hash([5; 32]), Hash([6; 32]), Hash([7; 32])], + ); + assert!(!received.has_next_page); + assert!(!received.has_previous_page); + Ok(()) } @@ -653,6 +757,7 @@ mod tests { )?; let sent = db_reader.get_txs_history_bc_sent( + None, PageInfo { order: true, limit_opt: None, @@ -662,6 +767,7 @@ mod tests { }), }, s1_hash, + None, )?; assert_eq!( sent.data @@ -674,6 +780,7 @@ mod tests { assert!(!sent.has_previous_page); let sent = db_reader.get_txs_history_bc_sent( + None, PageInfo { order: false, limit_opt: None, @@ -683,6 +790,7 @@ mod tests { }), }, s1_hash, + None, )?; assert_eq!( sent.data @@ -695,6 +803,7 @@ mod tests { assert!(!sent.has_previous_page); let sent = db_reader.get_txs_history_bc_sent( + None, PageInfo { order: false, limit_opt: None, @@ -704,6 +813,7 @@ mod tests { }), }, s1_hash, + None, )?; assert_eq!( sent.data diff --git a/rust-libs/modules/gva/gql/src/inputs.rs b/rust-libs/modules/gva/gql/src/inputs.rs index ccb343d0e178b4c45419cdcaa685ff5bc95d53a2..b904690941b7a6c4deac1cd019404f9cf3de96f6 100644 --- a/rust-libs/modules/gva/gql/src/inputs.rs +++ b/rust-libs/modules/gva/gql/src/inputs.rs @@ -15,6 +15,12 @@ use crate::*; +#[derive(async_graphql::InputObject, Clone, Copy, Default)] +pub(crate) struct TimeInterval { + pub(crate) from: Option<u64>, + pub(crate) to: Option<u64>, +} + #[derive(async_graphql::InputObject)] pub(crate) struct TxIssuer { /// Account script (default is a script needed all provided signers) diff --git a/rust-libs/modules/gva/gql/src/lib.rs b/rust-libs/modules/gva/gql/src/lib.rs index eeb1f925130e88f3ce76f54fde8a73bc8f089bc5..059b7533cee0db373b0a42fff2bf7b1911460c4b 100644 --- a/rust-libs/modules/gva/gql/src/lib.rs +++ b/rust-libs/modules/gva/gql/src/lib.rs @@ -150,13 +150,17 @@ mod tests { ) -> KvResult<Option<SourceAmount>>; fn get_txs_history_bc_received( &self, + from: Option<u64>, page_info: PageInfo<duniter_gva_dbs_reader::txs_history::TxBcCursor>, script_hash: Hash, + to: Option<u64>, ) -> KvResult<PagedData<VecDeque<duniter_gva_db::GvaTxDbV1>>>; fn get_txs_history_bc_sent( &self, + from: Option<u64>, page_info: PageInfo<duniter_gva_dbs_reader::txs_history::TxBcCursor>, script_hash: Hash, + to: Option<u64>, ) -> KvResult<PagedData<VecDeque<duniter_gva_db::GvaTxDbV1>>>; fn get_txs_history_mempool<TxsMpDb: 'static + TxsMpV2DbReadable>( &self, diff --git a/rust-libs/modules/gva/gql/src/queries/txs_history.rs b/rust-libs/modules/gva/gql/src/queries/txs_history.rs index f0307d9acf4292403936ebb85ad4334d39439b92..e1b250d76d94ff434d2cbaaa9a27c6d1bb522449 100644 --- a/rust-libs/modules/gva/gql/src/queries/txs_history.rs +++ b/rust-libs/modules/gva/gql/src/queries/txs_history.rs @@ -13,6 +13,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. +use crate::inputs::TimeInterval; use crate::*; use duniter_gva_db::GvaTxDbV1; use duniter_gva_dbs_reader::txs_history::TxBcCursor; @@ -29,6 +30,7 @@ impl TxsHistoryBlockchainQuery { ctx: &async_graphql::Context<'_>, #[graphql(desc = "pagination", default)] pagination: Pagination, script: PkOrScriptGva, + #[graphql(default)] time_interval: TimeInterval, ) -> async_graphql::Result<TxsHistoryBlockchainQueryInner> { let QueryContext { is_whitelisted } = ctx.data::<QueryContext>()?; let pagination = Pagination::convert_to_page_info(pagination, *is_whitelisted)?; @@ -36,6 +38,7 @@ impl TxsHistoryBlockchainQuery { Ok(TxsHistoryBlockchainQueryInner { pagination, script_hash, + time_interval, }) } } @@ -43,6 +46,7 @@ impl TxsHistoryBlockchainQuery { pub(crate) struct TxsHistoryBlockchainQueryInner { pub(crate) pagination: PageInfo<TxBcCursor>, pub(crate) script_hash: Hash, + pub(crate) time_interval: TimeInterval, } #[async_graphql::Object] @@ -59,14 +63,25 @@ impl TxsHistoryBlockchainQueryInner { let db_reader = data.dbs_reader(); let pagination = self.pagination; let script_hash = self.script_hash; - let sent_fut = data - .dbs_pool - .execute(move |_| db_reader.get_txs_history_bc_sent(pagination, script_hash)); + let time_interval = self.time_interval; + let sent_fut = data.dbs_pool.execute(move |_| { + db_reader.get_txs_history_bc_sent( + time_interval.from, + pagination, + script_hash, + time_interval.to, + ) + }); let db_reader = data.dbs_reader(); let script_hash = self.script_hash; - let received_fut = data - .dbs_pool - .execute(move |_| db_reader.get_txs_history_bc_received(pagination, script_hash)); + let received_fut = data.dbs_pool.execute(move |_| { + db_reader.get_txs_history_bc_received( + time_interval.from, + pagination, + script_hash, + time_interval.to, + ) + }); let (sent_res, received_res) = join(sent_fut, received_fut).await; let (sent, received) = (sent_res??, received_res??); @@ -136,9 +151,17 @@ impl TxsHistoryBlockchainQueryInner { let db_reader = data.dbs_reader(); let pagination = self.pagination; let script_hash = self.script_hash; + let time_interval = self.time_interval; let received = data .dbs_pool - .execute(move |_| db_reader.get_txs_history_bc_received(pagination, script_hash)) + .execute(move |_| { + db_reader.get_txs_history_bc_received( + time_interval.from, + pagination, + script_hash, + time_interval.to, + ) + }) .await??; let mut conn = Connection::new(received.has_previous_page, received.has_next_page); conn.append(received.data.into_iter().map(|db_tx| { @@ -163,9 +186,17 @@ impl TxsHistoryBlockchainQueryInner { let db_reader = data.dbs_reader(); let pagination = self.pagination; let script_hash = self.script_hash; + let time_interval = self.time_interval; let sent = data .dbs_pool - .execute(move |_| db_reader.get_txs_history_bc_sent(pagination, script_hash)) + .execute(move |_| { + db_reader.get_txs_history_bc_sent( + time_interval.from, + pagination, + script_hash, + time_interval.to, + ) + }) .await??; let mut conn = Connection::new(sent.has_previous_page, sent.has_next_page); conn.append(sent.data.into_iter().map(|db_tx| { @@ -232,11 +263,11 @@ mod tests { dbs_reader .expect_get_txs_history_bc_received() .times(1) - .returning(|_, _| Ok(PagedData::empty())); + .returning(|_, _, _, _| Ok(PagedData::empty())); dbs_reader .expect_get_txs_history_bc_sent() .times(1) - .returning(|_, _| { + .returning(|_, _, _, _| { let tx = TransactionDocumentV10::from_string_object( &TransactionDocumentV10Stringified { currency: "test".to_owned(),