From 027165f43302c7673a8c74bca8fff3e097896c4d Mon Sep 17 00:00:00 2001 From: chyngyz Date: Tue, 21 Jan 2025 10:50:35 +0600 Subject: [PATCH] Add method to get transactions after some hash --- .../ethereumkit/core/EthereumKit.kt | 4 ++ .../ethereumkit/core/Interfaces.kt | 2 + .../ethereumkit/core/TransactionManager.kt | 6 +++ .../core/storage/TransactionDao.kt | 2 +- .../core/storage/TransactionStorage.kt | 37 ++++++++++++++++++- 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/EthereumKit.kt b/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/EthereumKit.kt index 554906d8..921da3c6 100644 --- a/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/EthereumKit.kt +++ b/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/EthereumKit.kt @@ -176,6 +176,10 @@ class EthereumKit( return transactionManager.getFullTransactionSingle(hash) } + fun getFullTransactionsAfterSingle(hash: ByteArray?): Single> { + return transactionManager.getFullTransactionsAfterSingle(hash) + } + fun estimateGas(to: Address?, value: BigInteger, gasPrice: GasPrice): Single { // without address - provide default gas limit if (to == null) { diff --git a/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/Interfaces.kt b/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/Interfaces.kt index 2c632dc1..4d2901a4 100644 --- a/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/Interfaces.kt +++ b/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/Interfaces.kt @@ -82,6 +82,8 @@ interface ITransactionStorage { fun saveTags(tags: List) fun getDistinctTokenContractAddresses(): List + + fun getTransactionsAfterSingle(hash: ByteArray?): Single> } interface IEip20Storage { diff --git a/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/TransactionManager.kt b/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/TransactionManager.kt index 8cdcefc5..111ad2fe 100644 --- a/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/TransactionManager.kt +++ b/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/TransactionManager.kt @@ -146,6 +146,12 @@ class TransactionManager( return fullRpcTransactionSingle.map { decorationManager.decorateFullRpcTransaction(it) } } + fun getFullTransactionsAfterSingle(fromHash: ByteArray? = null): Single> = + storage.getTransactionsAfterSingle(fromHash) + .map { transactions -> + decorationManager.decorateTransactions(transactions) + } + private fun failPendingTransactions(): List { val pendingTransactions = storage.getPendingTransactions() diff --git a/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/storage/TransactionDao.kt b/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/storage/TransactionDao.kt index 3b60bd0c..71ae78a1 100644 --- a/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/storage/TransactionDao.kt +++ b/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/storage/TransactionDao.kt @@ -19,7 +19,7 @@ interface TransactionDao { fun getTransactions(hashes: List): List @RawQuery - fun getTransactionsBeforeAsync(query: SupportSQLiteQuery): Single> + fun getTransactionsByRawQuery(query: SupportSQLiteQuery): Single> @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(transactions: List) diff --git a/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/storage/TransactionStorage.kt b/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/storage/TransactionStorage.kt index 90de942f..ea88facd 100644 --- a/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/storage/TransactionStorage.kt +++ b/ethereumkit/src/main/java/io/horizontalsystems/ethereumkit/core/storage/TransactionStorage.kt @@ -72,7 +72,7 @@ class TransactionStorage(database: TransactionDatabase) : ITransactionStorage { $limitClause """ - return transactionDao.getTransactionsBeforeAsync(SimpleSQLiteQuery(sqlQuery)) + return transactionDao.getTransactionsByRawQuery(SimpleSQLiteQuery(sqlQuery)) } override fun save(transactions: List) { @@ -143,4 +143,39 @@ class TransactionStorage(database: TransactionDatabase) : ITransactionStorage { override fun getDistinctTokenContractAddresses(): List { return tagsDao.getDistinctTokenContractAddresses() } + + override fun getTransactionsAfterSingle(hash: ByteArray?): Single> { + val whereConditions = mutableListOf() + hash?.let { transactionDao.getTransaction(hash) }?.let { fromTransaction -> + val transactionIndex = fromTransaction.transactionIndex ?: 0 + val fromCondition = """ + ( + tx.timestamp > ${fromTransaction.timestamp} OR + ( + tx.timestamp = ${fromTransaction.timestamp} AND + tx.transactionIndex > $transactionIndex + ) OR + ( + tx.timestamp = ${fromTransaction.timestamp} AND + tx.transactionIndex = $transactionIndex AND + HEX(tx.hash) > "${fromTransaction.hash.toRawHexString().uppercase()}" + ) + ) + """ + + whereConditions.add(fromCondition) + } + + val whereClause = if (whereConditions.isNotEmpty()) "WHERE ${whereConditions.joinToString(" AND ")}" else "" + val orderClause = "ORDER BY tx.timestamp, tx.transactionIndex, HEX(tx.hash)" + + val sqlQuery = """ + SELECT tx.* + FROM `Transaction` as tx + $whereClause + $orderClause + """ + + return transactionDao.getTransactionsByRawQuery(SimpleSQLiteQuery(sqlQuery)) + } }