From 08f95d505dc465dddca535d4df439d55ec353baa Mon Sep 17 00:00:00 2001 From: Kevin Gorham Date: Tue, 14 Jan 2020 12:57:39 -0500 Subject: [PATCH] General fixes and improvements. --- src/main/java/cash/z/wallet/sdk/SdkSynchronizer.kt | 10 +++++----- .../cash/z/wallet/sdk/block/CompactBlockDbStore.kt | 2 +- .../cash/z/wallet/sdk/block/CompactBlockDownloader.kt | 3 ++- .../cash/z/wallet/sdk/block/CompactBlockProcessor.kt | 10 ++++++---- .../java/cash/z/wallet/sdk/ext/CurrencyFormatter.kt | 6 ++++-- src/main/java/cash/z/wallet/sdk/ext/WalletService.kt | 6 +++--- src/zcashmainnet/assets/zcash/saplingtree/692345.json | 6 ++++++ 7 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 src/zcashmainnet/assets/zcash/saplingtree/692345.json diff --git a/src/main/java/cash/z/wallet/sdk/SdkSynchronizer.kt b/src/main/java/cash/z/wallet/sdk/SdkSynchronizer.kt index 26c456f9..66475ea6 100644 --- a/src/main/java/cash/z/wallet/sdk/SdkSynchronizer.kt +++ b/src/main/java/cash/z/wallet/sdk/SdkSynchronizer.kt @@ -1,6 +1,8 @@ package cash.z.wallet.sdk import android.content.Context +import cash.z.wallet.sdk.Synchronizer.AddressType.Shielded +import cash.z.wallet.sdk.Synchronizer.AddressType.Transparent import cash.z.wallet.sdk.Synchronizer.Status.* import cash.z.wallet.sdk.block.CompactBlockDbStore import cash.z.wallet.sdk.block.CompactBlockDownloader @@ -316,13 +318,11 @@ class SdkSynchronizer internal constructor( override suspend fun validateAddress(address: String): Synchronizer.AddressType { return try { - isValidShieldedAddr(address) - Synchronizer.AddressType.Shielded + if (isValidShieldedAddr(address)) Shielded else Transparent } catch (zError: Throwable) { var message = zError.message try { - isValidTransparentAddr(address) - Synchronizer.AddressType.Transparent + if (isValidTransparentAddr(address)) Transparent else Shielded } catch (tError: Throwable) { Synchronizer.AddressType.Invalid( if (message != tError.message) "$message and ${tError.message}" else (message @@ -386,7 +386,7 @@ fun Synchronizer( lightwalletdHost: String = ZcashSdk.DEFAULT_LIGHTWALLETD_HOST, lightwalletdPort: Int = ZcashSdk.DEFAULT_LIGHTWALLETD_PORT, ledger: TransactionRepository = - PagedTransactionRepository(appContext, 10, rustBackend.dbDataPath), + PagedTransactionRepository(appContext, 1000, rustBackend.dbDataPath), // TODO: fix this pagesize bug, small pages should not crash the app. It crashes with: Uncaught Exception: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. and is probably related to FlowPagedList blockStore: CompactBlockStore = CompactBlockDbStore(appContext, rustBackend.dbCachePath), service: LightWalletService = LightWalletGrpcService(appContext, lightwalletdHost, lightwalletdPort), encoder: TransactionEncoder = WalletTransactionEncoder(rustBackend, ledger), diff --git a/src/main/java/cash/z/wallet/sdk/block/CompactBlockDbStore.kt b/src/main/java/cash/z/wallet/sdk/block/CompactBlockDbStore.kt index 810dcc97..5dc8962c 100644 --- a/src/main/java/cash/z/wallet/sdk/block/CompactBlockDbStore.kt +++ b/src/main/java/cash/z/wallet/sdk/block/CompactBlockDbStore.kt @@ -34,7 +34,7 @@ class CompactBlockDbStore( } override suspend fun getLatestHeight(): Int = withContext(IO) { - val lastBlock = Math.max(0, cacheDao.latestBlockHeight() - 1) + val lastBlock = Math.max(0, cacheDao.latestBlockHeight()) if (lastBlock < SAPLING_ACTIVATION_HEIGHT) -1 else lastBlock } diff --git a/src/main/java/cash/z/wallet/sdk/block/CompactBlockDownloader.kt b/src/main/java/cash/z/wallet/sdk/block/CompactBlockDownloader.kt index e3578b38..52c12d13 100644 --- a/src/main/java/cash/z/wallet/sdk/block/CompactBlockDownloader.kt +++ b/src/main/java/cash/z/wallet/sdk/block/CompactBlockDownloader.kt @@ -18,9 +18,10 @@ open class CompactBlockDownloader( val compactBlockStore: CompactBlockStore ) { - suspend fun downloadBlockRange(heightRange: IntRange) = withContext(IO) { + suspend fun downloadBlockRange(heightRange: IntRange): Int = withContext(IO) { val result = lightwalletService.getBlockRange(heightRange) compactBlockStore.write(result) + result.size } suspend fun rewindToHeight(height: Int) = withContext(IO) { diff --git a/src/main/java/cash/z/wallet/sdk/block/CompactBlockProcessor.kt b/src/main/java/cash/z/wallet/sdk/block/CompactBlockProcessor.kt index fac15853..477a53f5 100644 --- a/src/main/java/cash/z/wallet/sdk/block/CompactBlockProcessor.kt +++ b/src/main/java/cash/z/wallet/sdk/block/CompactBlockProcessor.kt @@ -174,13 +174,15 @@ class CompactBlockProcessor( twig("found $missingBlockCount missing blocks, downloading in $batches batches of ${DOWNLOAD_BATCH_SIZE}...") for (i in 1..batches) { retryUpTo(RETRIES) { - val end = min(range.first + (i * DOWNLOAD_BATCH_SIZE), range.last + 1) - twig("downloaded $downloadedBlockHeight..${(end - 1)} (batch $i of $batches)") { - downloader.downloadBlockRange(downloadedBlockHeight until end) + val end = min((range.first + (i * DOWNLOAD_BATCH_SIZE)) - 1, range.last) // subtract 1 on the first value because the range is inclusive + var count = 0 + twig("downloaded $downloadedBlockHeight..$end (batch $i of $batches) [${downloadedBlockHeight..end}]") { + count = downloader.downloadBlockRange(downloadedBlockHeight..end) } + twig("downloaded $count blocks!") progress = (i / batches.toFloat() * 100).roundToInt() - // only report during large downloads. TODO: allow for configuration of "large" _progress.send(progress) + updateProgress(lastDownloadedHeight = downloader.getLastDownloadedHeight().also { twig("updating lastDownloadedHeight=$it") }) downloadedBlockHeight = end } } diff --git a/src/main/java/cash/z/wallet/sdk/ext/CurrencyFormatter.kt b/src/main/java/cash/z/wallet/sdk/ext/CurrencyFormatter.kt index 32e89b38..7b7fe319 100644 --- a/src/main/java/cash/z/wallet/sdk/ext/CurrencyFormatter.kt +++ b/src/main/java/cash/z/wallet/sdk/ext/CurrencyFormatter.kt @@ -223,6 +223,8 @@ inline fun String?.safelyConvertToBigDecimal(): BigDecimal? { } } -inline fun String.abbreviatedAddress(startLength: Int = 8, endLength: Int = 8) = if (length > startLength + endLength) "${take(startLength)}…${takeLast(endLength)}" else this +inline fun String.toAbbreviatedAddress(startLength: Int = 8, endLength: Int = 8) = if (length > startLength + endLength) "${take(startLength)}…${takeLast(endLength)}" else this -internal inline fun String.masked(): String = if (startsWith("ztest") || startsWith("zs")) "****${takeLast(4)}" else "***masked***" \ No newline at end of file +internal inline fun String.masked(): String = if (startsWith("ztest") || startsWith("zs")) "****${takeLast(4)}" else "***masked***" + +inline fun String?.isShielded() = this != null && startsWith('z') \ No newline at end of file diff --git a/src/main/java/cash/z/wallet/sdk/ext/WalletService.kt b/src/main/java/cash/z/wallet/sdk/ext/WalletService.kt index efcb4204..9ebddd3e 100644 --- a/src/main/java/cash/z/wallet/sdk/ext/WalletService.kt +++ b/src/main/java/cash/z/wallet/sdk/ext/WalletService.kt @@ -6,16 +6,16 @@ import kotlinx.coroutines.delay import java.io.File import kotlin.random.Random -suspend inline fun retryUpTo(retries: Int, initialDelay: Int = 10, block: () -> Unit) { +suspend inline fun retryUpTo(retries: Int, initialDelayMillis: Long = 10L, block: (Int) -> Unit) { var failedAttempts = 0 while (failedAttempts < retries) { try { - block() + block(failedAttempts) return } catch (t: Throwable) { failedAttempts++ if (failedAttempts >= retries) throw t - val duration = Math.pow(initialDelay.toDouble(), failedAttempts.toDouble()).toLong() + val duration = Math.pow(initialDelayMillis.toDouble(), failedAttempts.toDouble()).toLong() twig("failed due to $t retrying (${failedAttempts + 1}/$retries) in ${duration}s...") delay(duration) } diff --git a/src/zcashmainnet/assets/zcash/saplingtree/692345.json b/src/zcashmainnet/assets/zcash/saplingtree/692345.json new file mode 100644 index 00000000..3e2f5182 --- /dev/null +++ b/src/zcashmainnet/assets/zcash/saplingtree/692345.json @@ -0,0 +1,6 @@ +{ + "height": 692345, + "hash": "0000000002584662ea3fb1969a65f05cf1e0c82581b885fbd723eed6ba818e99", + "time": 1579021581, + "tree": "01a30b15d800be77c5c959f57466a2c6dcf3e583010c1308a6956e23ec1b4658180140ead0f57ec26315bc14ac9a03ee843f34d080f41d2a682d824a02d73569446011000001d4d84c0e533c23813285e3849abff78ff36d2fc4b82c35061aed5e20a13c1859000191e51cd5f2f0afa0de7cd18fde39feb724bdc225fc25a9c75acbae1b641a7719016c33f322bc0205623943faa2a270b2925176cfc642da9625bd567e06b13c4d14000193726f6855f49bda4fb05a256bfcb17bf6ebac59b69ef9bfa73d69ac65ab2c2e01875259d77037ad0de128f071d2b85dfefd4d14c29e3fbd573abf843ebe5d830d0001d0c515cd513b49e397bf96d895a941aed4869ff2ff925939a34572c078dc16470121c1efd29f85680334050ee2a7e0d09fde474f90e573d85b7c9d337a5465625a0000000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260" +} \ No newline at end of file