Fix: change rewind behavior to correct for witnesses
Addresses SDK side of https://github.com/zcash/librustzcash/issues/373
This commit is contained in:
parent
e07317c7d5
commit
5dd0df7619
|
@ -303,8 +303,11 @@ class SdkSynchronizer internal constructor(
|
|||
)
|
||||
}
|
||||
|
||||
override suspend fun rewindToHeight(height: Int, alsoClearBlockCache: Boolean) {
|
||||
processor.rewindToHeight(height, alsoClearBlockCache)
|
||||
override suspend fun getNearestRewindHeight(height: Int): Int =
|
||||
processor.getNearestRewindHeight(height)
|
||||
|
||||
override suspend fun rewindToNearestHeight(height: Int, alsoClearBlockCache: Boolean) {
|
||||
processor.rewindToNearestHeight(height, alsoClearBlockCache)
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -385,7 +388,7 @@ class SdkSynchronizer internal constructor(
|
|||
twig("Synchronizer onReady complete. Processor start has exited!")
|
||||
}
|
||||
|
||||
private fun onCriticalError(unused: CoroutineContext, error: Throwable) {
|
||||
private fun onCriticalError(unused: CoroutineContext?, error: Throwable) {
|
||||
twig("********")
|
||||
twig("******** ERROR: $error")
|
||||
if (error.cause != null) twig("******** caused by ${error.cause}")
|
||||
|
|
|
@ -281,7 +281,15 @@ interface Synchronizer {
|
|||
*/
|
||||
suspend fun getTransparentBalance(tAddr: String): WalletBalance
|
||||
|
||||
suspend fun rewindToHeight(height: Int, alsoClearBlockCache: Boolean = false)
|
||||
suspend fun getNearestRewindHeight(height: Int): Int
|
||||
|
||||
/**
|
||||
* Returns the safest height to which we can rewind, given a desire to rewind to the height
|
||||
* provided. Due to how witness incrementing works, a wallet cannot simply rewind to any
|
||||
* arbitrary height. This handles all that complexity yet remains flexible in the future as
|
||||
* improvements are made.
|
||||
*/
|
||||
suspend fun rewindToNearestHeight(height: Int, alsoClearBlockCache: Boolean = false)
|
||||
|
||||
//
|
||||
// Error Handling
|
||||
|
|
|
@ -588,7 +588,15 @@ class CompactBlockProcessor(
|
|||
determineLowerBound(errorHeight).let { lowerBound ->
|
||||
twig("handling chain error at $errorHeight by rewinding to block $lowerBound")
|
||||
onChainErrorListener?.invoke(errorHeight, lowerBound)
|
||||
rewindToHeight(lowerBound, true)
|
||||
rewindToNearestHeight(lowerBound, true)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getNearestRewindHeight(height: Int): Int {
|
||||
return if (height < lowerBoundHeight) {
|
||||
lowerBoundHeight
|
||||
} else {
|
||||
rustBackend.getNearestRewindHeight(height)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -596,12 +604,11 @@ class CompactBlockProcessor(
|
|||
* @param alsoClearBlockCache when true, also clear the block cache which forces a redownload of
|
||||
* blocks. Otherwise, the cached blocks will be used in the rescan, which in most cases, is fine.
|
||||
*/
|
||||
suspend fun rewindToHeight(height: Int, alsoClearBlockCache: Boolean = false) = withContext(IO) {
|
||||
suspend fun rewindToNearestHeight(height: Int, alsoClearBlockCache: Boolean = false) = withContext(IO) {
|
||||
processingMutex.withLockLogged("rewindToHeight") {
|
||||
val lastScannedHeight = currentInfo.lastScannedHeight
|
||||
val targetHeight = determineTargetHeight(height)
|
||||
val targetHeight = getNearestRewindHeight(height)
|
||||
twig("Rewinding from $lastScannedHeight to requested height: $height using target height: $targetHeight")
|
||||
// TODO: think about how we might pause all processing during a rewind
|
||||
if (targetHeight < lastScannedHeight) {
|
||||
rustBackend.rewindToHeight(targetHeight)
|
||||
} else {
|
||||
|
@ -681,19 +688,6 @@ class CompactBlockProcessor(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a height to rewind to, check whether it goes beyond our checkpoint. Of so, we cannot
|
||||
* use that height so go to our checkpoint instead.
|
||||
*/
|
||||
private fun determineTargetHeight(rewindHeight: Int): Int {
|
||||
return if (rewindHeight == network.saplingActivationHeight) {
|
||||
rewindHeight
|
||||
} else {
|
||||
val checkpointHeight = repository.firstScannedHeight()
|
||||
rewindHeight.coerceAtLeast(checkpointHeight)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll on time boundaries. Per Issue #95, we want to avoid exposing computation time to a
|
||||
* network observer. Instead, we poll at regular time intervals that are large enough for all
|
||||
|
|
|
@ -97,6 +97,8 @@ class RustBackend private constructor() : RustBackendWelding {
|
|||
|
||||
override fun validateCombinedChain() = validateCombinedChain(pathCacheDb, pathDataDb, networkId = network.id,)
|
||||
|
||||
override fun getNearestRewindHeight(height: Int): Int = getNearestRewindHeight(pathDataDb, height, networkId = network.id)
|
||||
|
||||
/**
|
||||
* Deletes data for all blocks above the given height. Boils down to:
|
||||
*
|
||||
|
@ -315,6 +317,13 @@ class RustBackend private constructor() : RustBackendWelding {
|
|||
networkId: Int,
|
||||
): Int
|
||||
|
||||
@JvmStatic
|
||||
private external fun getNearestRewindHeight(
|
||||
dbDataPath: String,
|
||||
height: Int,
|
||||
networkId: Int,
|
||||
): Int
|
||||
|
||||
@JvmStatic
|
||||
private external fun rewindToHeight(
|
||||
dbDataPath: String,
|
||||
|
|
|
@ -59,6 +59,8 @@ interface RustBackendWelding {
|
|||
|
||||
// fun parseTransactionDataList(tdl: LocalRpcTypes.TransactionDataList): LocalRpcTypes.TransparentTransactionList
|
||||
|
||||
fun getNearestRewindHeight(height: Int): Int
|
||||
|
||||
fun rewindToHeight(height: Int): Boolean
|
||||
|
||||
fun scanBlocks(limit: Int = -1): Boolean
|
||||
|
|
Loading…
Reference in New Issue