General fixes and improvements.

This commit is contained in:
Kevin Gorham 2020-01-14 12:57:39 -05:00
parent 3ad1a056a6
commit 08f95d505d
No known key found for this signature in database
GPG Key ID: CCA55602DF49FC38
7 changed files with 27 additions and 16 deletions

View File

@ -1,6 +1,8 @@
package cash.z.wallet.sdk package cash.z.wallet.sdk
import android.content.Context 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.Synchronizer.Status.*
import cash.z.wallet.sdk.block.CompactBlockDbStore import cash.z.wallet.sdk.block.CompactBlockDbStore
import cash.z.wallet.sdk.block.CompactBlockDownloader import cash.z.wallet.sdk.block.CompactBlockDownloader
@ -316,13 +318,11 @@ class SdkSynchronizer internal constructor(
override suspend fun validateAddress(address: String): Synchronizer.AddressType { override suspend fun validateAddress(address: String): Synchronizer.AddressType {
return try { return try {
isValidShieldedAddr(address) if (isValidShieldedAddr(address)) Shielded else Transparent
Synchronizer.AddressType.Shielded
} catch (zError: Throwable) { } catch (zError: Throwable) {
var message = zError.message var message = zError.message
try { try {
isValidTransparentAddr(address) if (isValidTransparentAddr(address)) Transparent else Shielded
Synchronizer.AddressType.Transparent
} catch (tError: Throwable) { } catch (tError: Throwable) {
Synchronizer.AddressType.Invalid( Synchronizer.AddressType.Invalid(
if (message != tError.message) "$message and ${tError.message}" else (message if (message != tError.message) "$message and ${tError.message}" else (message
@ -386,7 +386,7 @@ fun Synchronizer(
lightwalletdHost: String = ZcashSdk.DEFAULT_LIGHTWALLETD_HOST, lightwalletdHost: String = ZcashSdk.DEFAULT_LIGHTWALLETD_HOST,
lightwalletdPort: Int = ZcashSdk.DEFAULT_LIGHTWALLETD_PORT, lightwalletdPort: Int = ZcashSdk.DEFAULT_LIGHTWALLETD_PORT,
ledger: TransactionRepository = 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), blockStore: CompactBlockStore = CompactBlockDbStore(appContext, rustBackend.dbCachePath),
service: LightWalletService = LightWalletGrpcService(appContext, lightwalletdHost, lightwalletdPort), service: LightWalletService = LightWalletGrpcService(appContext, lightwalletdHost, lightwalletdPort),
encoder: TransactionEncoder = WalletTransactionEncoder(rustBackend, ledger), encoder: TransactionEncoder = WalletTransactionEncoder(rustBackend, ledger),

View File

@ -34,7 +34,7 @@ class CompactBlockDbStore(
} }
override suspend fun getLatestHeight(): Int = withContext(IO) { 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 if (lastBlock < SAPLING_ACTIVATION_HEIGHT) -1 else lastBlock
} }

View File

@ -18,9 +18,10 @@ open class CompactBlockDownloader(
val compactBlockStore: CompactBlockStore val compactBlockStore: CompactBlockStore
) { ) {
suspend fun downloadBlockRange(heightRange: IntRange) = withContext(IO) { suspend fun downloadBlockRange(heightRange: IntRange): Int = withContext(IO) {
val result = lightwalletService.getBlockRange(heightRange) val result = lightwalletService.getBlockRange(heightRange)
compactBlockStore.write(result) compactBlockStore.write(result)
result.size
} }
suspend fun rewindToHeight(height: Int) = withContext(IO) { suspend fun rewindToHeight(height: Int) = withContext(IO) {

View File

@ -174,13 +174,15 @@ class CompactBlockProcessor(
twig("found $missingBlockCount missing blocks, downloading in $batches batches of ${DOWNLOAD_BATCH_SIZE}...") twig("found $missingBlockCount missing blocks, downloading in $batches batches of ${DOWNLOAD_BATCH_SIZE}...")
for (i in 1..batches) { for (i in 1..batches) {
retryUpTo(RETRIES) { retryUpTo(RETRIES) {
val end = min(range.first + (i * DOWNLOAD_BATCH_SIZE), range.last + 1) val end = min((range.first + (i * DOWNLOAD_BATCH_SIZE)) - 1, range.last) // subtract 1 on the first value because the range is inclusive
twig("downloaded $downloadedBlockHeight..${(end - 1)} (batch $i of $batches)") { var count = 0
downloader.downloadBlockRange(downloadedBlockHeight until end) 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() progress = (i / batches.toFloat() * 100).roundToInt()
// only report during large downloads. TODO: allow for configuration of "large"
_progress.send(progress) _progress.send(progress)
updateProgress(lastDownloadedHeight = downloader.getLastDownloadedHeight().also { twig("updating lastDownloadedHeight=$it") })
downloadedBlockHeight = end downloadedBlockHeight = end
} }
} }

View File

@ -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***" internal inline fun String.masked(): String = if (startsWith("ztest") || startsWith("zs")) "****${takeLast(4)}" else "***masked***"
inline fun String?.isShielded() = this != null && startsWith('z')

View File

@ -6,16 +6,16 @@ import kotlinx.coroutines.delay
import java.io.File import java.io.File
import kotlin.random.Random 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 var failedAttempts = 0
while (failedAttempts < retries) { while (failedAttempts < retries) {
try { try {
block() block(failedAttempts)
return return
} catch (t: Throwable) { } catch (t: Throwable) {
failedAttempts++ failedAttempts++
if (failedAttempts >= retries) throw t 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...") twig("failed due to $t retrying (${failedAttempts + 1}/$retries) in ${duration}s...")
delay(duration) delay(duration)
} }

View File

@ -0,0 +1,6 @@
{
"height": 692345,
"hash": "0000000002584662ea3fb1969a65f05cf1e0c82581b885fbd723eed6ba818e99",
"time": 1579021581,
"tree": "01a30b15d800be77c5c959f57466a2c6dcf3e583010c1308a6956e23ec1b4658180140ead0f57ec26315bc14ac9a03ee843f34d080f41d2a682d824a02d73569446011000001d4d84c0e533c23813285e3849abff78ff36d2fc4b82c35061aed5e20a13c1859000191e51cd5f2f0afa0de7cd18fde39feb724bdc225fc25a9c75acbae1b641a7719016c33f322bc0205623943faa2a270b2925176cfc642da9625bd567e06b13c4d14000193726f6855f49bda4fb05a256bfcb17bf6ebac59b69ef9bfa73d69ac65ab2c2e01875259d77037ad0de128f071d2b85dfefd4d14c29e3fbd573abf843ebe5d830d0001d0c515cd513b49e397bf96d895a941aed4869ff2ff925939a34572c078dc16470121c1efd29f85680334050ee2a7e0d09fde474f90e573d85b7c9d337a5465625a0000000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
}