diff --git a/backend-lib/Cargo.lock b/backend-lib/Cargo.lock index 69c2e31b0..3d02ac21a 100644 --- a/backend-lib/Cargo.lock +++ b/backend-lib/Cargo.lock @@ -1111,7 +1111,7 @@ dependencies = [ [[package]] name = "equihash" version = "0.2.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=7f7b685b99132505a0fe4ba588f329e3516e9669#7f7b685b99132505a0fe4ba588f329e3516e9669" +source = "git+https://github.com/zcash/librustzcash.git?rev=9cfce187f0ad93869fa20ada5f011bab64ccc9c5#9cfce187f0ad93869fa20ada5f011bab64ccc9c5" dependencies = [ "blake2b_simd", "byteorder", @@ -1147,7 +1147,7 @@ dependencies = [ [[package]] name = "f4jumble" version = "0.1.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=7f7b685b99132505a0fe4ba588f329e3516e9669#7f7b685b99132505a0fe4ba588f329e3516e9669" +source = "git+https://github.com/zcash/librustzcash.git?rev=9cfce187f0ad93869fa20ada5f011bab64ccc9c5#9cfce187f0ad93869fa20ada5f011bab64ccc9c5" dependencies = [ "blake2b_simd", ] @@ -4990,7 +4990,7 @@ dependencies = [ [[package]] name = "zcash_address" version = "0.3.2" -source = "git+https://github.com/zcash/librustzcash.git?rev=7f7b685b99132505a0fe4ba588f329e3516e9669#7f7b685b99132505a0fe4ba588f329e3516e9669" +source = "git+https://github.com/zcash/librustzcash.git?rev=9cfce187f0ad93869fa20ada5f011bab64ccc9c5#9cfce187f0ad93869fa20ada5f011bab64ccc9c5" dependencies = [ "bech32", "bs58", @@ -5002,7 +5002,7 @@ dependencies = [ [[package]] name = "zcash_client_backend" version = "0.12.1" -source = "git+https://github.com/zcash/librustzcash.git?rev=7f7b685b99132505a0fe4ba588f329e3516e9669#7f7b685b99132505a0fe4ba588f329e3516e9669" +source = "git+https://github.com/zcash/librustzcash.git?rev=9cfce187f0ad93869fa20ada5f011bab64ccc9c5#9cfce187f0ad93869fa20ada5f011bab64ccc9c5" dependencies = [ "arti-client", "async-trait", @@ -5058,7 +5058,7 @@ dependencies = [ [[package]] name = "zcash_client_sqlite" version = "0.10.3" -source = "git+https://github.com/zcash/librustzcash.git?rev=7f7b685b99132505a0fe4ba588f329e3516e9669#7f7b685b99132505a0fe4ba588f329e3516e9669" +source = "git+https://github.com/zcash/librustzcash.git?rev=9cfce187f0ad93869fa20ada5f011bab64ccc9c5#9cfce187f0ad93869fa20ada5f011bab64ccc9c5" dependencies = [ "bip32", "bs58", @@ -5094,7 +5094,7 @@ dependencies = [ [[package]] name = "zcash_encoding" version = "0.2.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=7f7b685b99132505a0fe4ba588f329e3516e9669#7f7b685b99132505a0fe4ba588f329e3516e9669" +source = "git+https://github.com/zcash/librustzcash.git?rev=9cfce187f0ad93869fa20ada5f011bab64ccc9c5#9cfce187f0ad93869fa20ada5f011bab64ccc9c5" dependencies = [ "byteorder", "nonempty", @@ -5103,7 +5103,7 @@ dependencies = [ [[package]] name = "zcash_keys" version = "0.2.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=7f7b685b99132505a0fe4ba588f329e3516e9669#7f7b685b99132505a0fe4ba588f329e3516e9669" +source = "git+https://github.com/zcash/librustzcash.git?rev=9cfce187f0ad93869fa20ada5f011bab64ccc9c5#9cfce187f0ad93869fa20ada5f011bab64ccc9c5" dependencies = [ "bech32", "bip32", @@ -5144,7 +5144,7 @@ dependencies = [ [[package]] name = "zcash_primitives" version = "0.15.1" -source = "git+https://github.com/zcash/librustzcash.git?rev=7f7b685b99132505a0fe4ba588f329e3516e9669#7f7b685b99132505a0fe4ba588f329e3516e9669" +source = "git+https://github.com/zcash/librustzcash.git?rev=9cfce187f0ad93869fa20ada5f011bab64ccc9c5#9cfce187f0ad93869fa20ada5f011bab64ccc9c5" dependencies = [ "aes", "bip32", @@ -5182,7 +5182,7 @@ dependencies = [ [[package]] name = "zcash_proofs" version = "0.15.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=7f7b685b99132505a0fe4ba588f329e3516e9669#7f7b685b99132505a0fe4ba588f329e3516e9669" +source = "git+https://github.com/zcash/librustzcash.git?rev=9cfce187f0ad93869fa20ada5f011bab64ccc9c5#9cfce187f0ad93869fa20ada5f011bab64ccc9c5" dependencies = [ "bellman", "blake2b_simd", @@ -5204,7 +5204,7 @@ dependencies = [ [[package]] name = "zcash_protocol" version = "0.1.1" -source = "git+https://github.com/zcash/librustzcash.git?rev=7f7b685b99132505a0fe4ba588f329e3516e9669#7f7b685b99132505a0fe4ba588f329e3516e9669" +source = "git+https://github.com/zcash/librustzcash.git?rev=9cfce187f0ad93869fa20ada5f011bab64ccc9c5#9cfce187f0ad93869fa20ada5f011bab64ccc9c5" dependencies = [ "document-features", "memuse", @@ -5294,7 +5294,7 @@ dependencies = [ [[package]] name = "zip321" version = "0.0.0" -source = "git+https://github.com/zcash/librustzcash.git?rev=7f7b685b99132505a0fe4ba588f329e3516e9669#7f7b685b99132505a0fe4ba588f329e3516e9669" +source = "git+https://github.com/zcash/librustzcash.git?rev=9cfce187f0ad93869fa20ada5f011bab64ccc9c5#9cfce187f0ad93869fa20ada5f011bab64ccc9c5" dependencies = [ "base64 0.21.7", "nom", diff --git a/backend-lib/Cargo.toml b/backend-lib/Cargo.toml index df7ae4715..2e1980124 100644 --- a/backend-lib/Cargo.toml +++ b/backend-lib/Cargo.toml @@ -69,10 +69,10 @@ crate-type = ["staticlib", "cdylib"] [patch.crates-io] incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree", rev = "337f59179eda51261e9ddfc6b18e8fb84ea277c9" } shardtree = { git = "https://github.com/zcash/incrementalmerkletree", rev = "337f59179eda51261e9ddfc6b18e8fb84ea277c9" } -zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "7f7b685b99132505a0fe4ba588f329e3516e9669" } -zcash_client_backend = { git = "https://github.com/zcash/librustzcash.git", rev = "7f7b685b99132505a0fe4ba588f329e3516e9669" } -zcash_client_sqlite = { git = "https://github.com/zcash/librustzcash.git", rev = "7f7b685b99132505a0fe4ba588f329e3516e9669" } -zcash_encoding = { git = "https://github.com/zcash/librustzcash.git", rev = "7f7b685b99132505a0fe4ba588f329e3516e9669" } -zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "7f7b685b99132505a0fe4ba588f329e3516e9669" } -zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "7f7b685b99132505a0fe4ba588f329e3516e9669" } -zcash_protocol = { git = "https://github.com/zcash/librustzcash.git", rev = "7f7b685b99132505a0fe4ba588f329e3516e9669" } +zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "9cfce187f0ad93869fa20ada5f011bab64ccc9c5" } +zcash_client_backend = { git = "https://github.com/zcash/librustzcash.git", rev = "9cfce187f0ad93869fa20ada5f011bab64ccc9c5" } +zcash_client_sqlite = { git = "https://github.com/zcash/librustzcash.git", rev = "9cfce187f0ad93869fa20ada5f011bab64ccc9c5" } +zcash_encoding = { git = "https://github.com/zcash/librustzcash.git", rev = "9cfce187f0ad93869fa20ada5f011bab64ccc9c5" } +zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "9cfce187f0ad93869fa20ada5f011bab64ccc9c5" } +zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "9cfce187f0ad93869fa20ada5f011bab64ccc9c5" } +zcash_protocol = { git = "https://github.com/zcash/librustzcash.git", rev = "9cfce187f0ad93869fa20ada5f011bab64ccc9c5" } diff --git a/backend-lib/src/main/java/cash/z/ecc/android/sdk/internal/Backend.kt b/backend-lib/src/main/java/cash/z/ecc/android/sdk/internal/Backend.kt index 885587c5e..6b9c92655 100644 --- a/backend-lib/src/main/java/cash/z/ecc/android/sdk/internal/Backend.kt +++ b/backend-lib/src/main/java/cash/z/ecc/android/sdk/internal/Backend.kt @@ -39,7 +39,14 @@ interface Backend { unifiedSpendingKey: ByteArray ): List - suspend fun decryptAndStoreTransaction(tx: ByteArray) + /** + * @throws RuntimeException as a common indicator of the operation failure + */ + @Throws(RuntimeException::class) + suspend fun decryptAndStoreTransaction( + tx: ByteArray, + minedHeight: Long? + ) /** * Sets up the internal structure of the data database. diff --git a/backend-lib/src/main/java/cash/z/ecc/android/sdk/internal/jni/RustBackend.kt b/backend-lib/src/main/java/cash/z/ecc/android/sdk/internal/jni/RustBackend.kt index 943d341aa..21a4b70c4 100644 --- a/backend-lib/src/main/java/cash/z/ecc/android/sdk/internal/jni/RustBackend.kt +++ b/backend-lib/src/main/java/cash/z/ecc/android/sdk/internal/jni/RustBackend.kt @@ -295,14 +295,17 @@ class RustBackend private constructor( } } - override suspend fun decryptAndStoreTransaction(tx: ByteArray) = - withContext(SdkDispatchers.DATABASE_IO) { - decryptAndStoreTransaction( - dataDbFile.absolutePath, - tx, - networkId = networkId - ) - } + override suspend fun decryptAndStoreTransaction( + tx: ByteArray, + minedHeight: Long? + ) = withContext(SdkDispatchers.DATABASE_IO) { + decryptAndStoreTransaction( + dataDbFile.absolutePath, + tx, + minedHeight = minedHeight ?: -1, + networkId = networkId + ) + } override suspend fun proposeTransfer( account: Int, @@ -616,6 +619,7 @@ class RustBackend private constructor( private external fun decryptAndStoreTransaction( dbDataPath: String, tx: ByteArray, + minedHeight: Long, networkId: Int ) diff --git a/backend-lib/src/main/rust/lib.rs b/backend-lib/src/main/rust/lib.rs index 7d750593e..62640518e 100644 --- a/backend-lib/src/main/rust/lib.rs +++ b/backend-lib/src/main/rust/lib.rs @@ -369,7 +369,7 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_createAcc let account = db_data.get_account(account_id)?.expect("just created"); let account_index = match account.source() { AccountSource::Derived { account_index, .. } => account_index, - AccountSource::Imported => unreachable!("just created"), + AccountSource::Imported { .. } => unreachable!("just created"), }; Ok(encode_usk(env, account_index, usk)?.into_raw()) @@ -1327,7 +1327,9 @@ fn encode_wallet_summary<'a, P: Parameters>( .source() { AccountSource::Derived { account_index, .. } => account_index, - AccountSource::Imported => unreachable!("Imported accounts are unimplemented"), + AccountSource::Imported { .. } => { + unreachable!("Imported accounts are unimplemented") + } }; Ok::<_, anyhow::Error>((account_index, balance)) }) @@ -1556,6 +1558,7 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_decryptAn _: JClass<'local>, db_data: JString<'local>, tx: JByteArray<'local>, + mined_height: jlong, network_id: jint, ) -> jboolean { let res = catch_unwind(&mut env, |env| { @@ -1570,8 +1573,9 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_decryptAn // - v5 and above transactions ignore the argument, and parse the correct value // from their encoding. let tx = Transaction::read(&tx_bytes[..], BranchId::Sapling)?; + let mined_height = BlockHeight::try_from(mined_height).ok(); - match decrypt_and_store_transaction(&network, &mut db_data, &tx) { + match decrypt_and_store_transaction(&network, &mut db_data, &tx, mined_height) { Ok(()) => Ok(JNI_TRUE), Err(e) => Err(anyhow!("Error while decrypting transaction: {}", e)), } diff --git a/sdk-lib/src/androidTest/java/cash/z/ecc/fixture/FakeRustBackend.kt b/sdk-lib/src/androidTest/java/cash/z/ecc/fixture/FakeRustBackend.kt index a3627b68a..b067f7b6a 100644 --- a/sdk-lib/src/androidTest/java/cash/z/ecc/fixture/FakeRustBackend.kt +++ b/sdk-lib/src/androidTest/java/cash/z/ecc/fixture/FakeRustBackend.kt @@ -104,8 +104,10 @@ internal class FakeRustBackend( TODO("Not yet implemented") } - override suspend fun decryptAndStoreTransaction(tx: ByteArray) = - error("Intentionally not implemented in mocked FakeRustBackend implementation.") + override suspend fun decryptAndStoreTransaction( + tx: ByteArray, + minedHeight: Long? + ) = error("Intentionally not implemented in mocked FakeRustBackend implementation.") override suspend fun initDataDb(seed: ByteArray?): Int = error("Intentionally not implemented in mocked FakeRustBackend implementation.") diff --git a/sdk-lib/src/main/java/cash/z/ecc/android/sdk/block/processor/CompactBlockProcessor.kt b/sdk-lib/src/main/java/cash/z/ecc/android/sdk/block/processor/CompactBlockProcessor.kt index 05dd15b6b..811364583 100644 --- a/sdk-lib/src/main/java/cash/z/ecc/android/sdk/block/processor/CompactBlockProcessor.kt +++ b/sdk-lib/src/main/java/cash/z/ecc/android/sdk/block/processor/CompactBlockProcessor.kt @@ -1574,7 +1574,8 @@ class CompactBlockProcessor internal constructor( range = currentEnhancingRange, repository = repository, backend = backend, - downloader = downloader + downloader = downloader, + network = network ).collect { enhancingResult -> Twig.info { "Enhancing result: $enhancingResult" } resultState = @@ -1838,7 +1839,8 @@ class CompactBlockProcessor internal constructor( range: ClosedRange, repository: DerivedDataRepository, backend: TypesafeBackend, - downloader: CompactBlockDownloader + downloader: CompactBlockDownloader, + network: ZcashNetwork ): Flow = flow { Twig.debug { "Enhancing transaction details for blocks $range" } @@ -1856,7 +1858,7 @@ class CompactBlockProcessor internal constructor( } newTxs.filter { it.minedHeight != null }.onEach { newTransaction -> - val trEnhanceResult = enhanceTransaction(newTransaction, backend, downloader) + val trEnhanceResult = enhanceTransaction(newTransaction, backend, downloader, network) if (trEnhanceResult is SyncingResult.EnhanceFailed) { Twig.error { "Encountered transaction enhancing error: ${trEnhanceResult.exception}" } emit(trEnhanceResult) @@ -1872,7 +1874,8 @@ class CompactBlockProcessor internal constructor( private suspend fun enhanceTransaction( transaction: DbTransactionOverview, backend: TypesafeBackend, - downloader: CompactBlockDownloader + downloader: CompactBlockDownloader, + network: ZcashNetwork ): SyncingResult { Twig.debug { "Starting enhancing transaction (txid:${transaction.txIdString()} block:${transaction @@ -1895,7 +1898,8 @@ class CompactBlockProcessor internal constructor( transactionId = transaction.txIdString(), rawTransactionId = transaction.rawId.byteArray, minedHeight = transaction.minedHeight, - downloader = downloader + downloader = downloader, + network = network ) // Decrypting and storing transaction is run just once, since we consider it more stable @@ -1904,8 +1908,8 @@ class CompactBlockProcessor internal constructor( "(txid:${transaction.txIdString()} block:${transaction.minedHeight})" } decryptTransaction( - transactionData = transactionData, - minedHeight = transaction.minedHeight, + transactionData = transactionData.first, + minedHeight = transactionData.second, backend = backend ) @@ -1931,10 +1935,11 @@ class CompactBlockProcessor internal constructor( transactionId: String, rawTransactionId: ByteArray, minedHeight: BlockHeight, - downloader: CompactBlockDownloader - ): ByteArray { + downloader: CompactBlockDownloader, + network: ZcashNetwork + ): Pair { val traceScope = TraceScope("CompactBlockProcessor.fetchTransaction") - var transactionDataResult: ByteArray? = null + var transactionDataResult: Pair? = null retryUpToAndThrow(TRANSACTION_FETCH_RETRIES) { failedAttempts -> if (failedAttempts == 0) { Twig.debug { "Starting to fetch transaction (txid:$transactionId, block:$minedHeight)" } @@ -1946,7 +1951,10 @@ class CompactBlockProcessor internal constructor( } when (val response = downloader.fetchTransaction(rawTransactionId)) { is Response.Success -> { - transactionDataResult = response.result.data + val currentMinedHeight = + runCatching { response.result.height.toBlockHeight(network) } + .getOrNull() + transactionDataResult = Pair(response.result.data, currentMinedHeight) } is Response.Failure -> { throw EnhanceTxDownloadError(minedHeight, response.toThrowable()) @@ -1961,12 +1969,12 @@ class CompactBlockProcessor internal constructor( @Throws(EnhanceTxDecryptError::class) private suspend fun decryptTransaction( transactionData: ByteArray, - minedHeight: BlockHeight, + minedHeight: BlockHeight?, backend: TypesafeBackend, ) { val traceScope = TraceScope("CompactBlockProcessor.decryptTransaction") runCatching { - backend.decryptAndStoreTransaction(transactionData) + backend.decryptAndStoreTransaction(transactionData, minedHeight) }.onFailure { traceScope.end() throw EnhanceTxDecryptError(minedHeight, it) diff --git a/sdk-lib/src/main/java/cash/z/ecc/android/sdk/exception/Exceptions.kt b/sdk-lib/src/main/java/cash/z/ecc/android/sdk/exception/Exceptions.kt index bbb7000a9..3a8e31046 100644 --- a/sdk-lib/src/main/java/cash/z/ecc/android/sdk/exception/Exceptions.kt +++ b/sdk-lib/src/main/java/cash/z/ecc/android/sdk/exception/Exceptions.kt @@ -98,7 +98,7 @@ sealed class CompactBlockProcessorException(message: String, cause: Throwable? = open class EnhanceTransactionError( message: String, - val height: BlockHeight, + val height: BlockHeight?, cause: Throwable ) : CompactBlockProcessorException(message, cause) { class EnhanceTxDownloadError( @@ -111,7 +111,7 @@ sealed class CompactBlockProcessorException(message: String, cause: Throwable? = ) class EnhanceTxDecryptError( - height: BlockHeight, + height: BlockHeight?, cause: Throwable ) : EnhanceTransactionError( "Error while attempting to decrypt and store a transaction to enhance", diff --git a/sdk-lib/src/main/java/cash/z/ecc/android/sdk/internal/TypesafeBackend.kt b/sdk-lib/src/main/java/cash/z/ecc/android/sdk/internal/TypesafeBackend.kt index 4981774d1..2ae7c200e 100644 --- a/sdk-lib/src/main/java/cash/z/ecc/android/sdk/internal/TypesafeBackend.kt +++ b/sdk-lib/src/main/java/cash/z/ecc/android/sdk/internal/TypesafeBackend.kt @@ -149,7 +149,10 @@ internal interface TypesafeBackend { @Throws(RuntimeException::class) suspend fun suggestScanRanges(): List - suspend fun decryptAndStoreTransaction(tx: ByteArray) + suspend fun decryptAndStoreTransaction( + tx: ByteArray, + minedHeight: BlockHeight? + ) fun getSaplingReceiver(ua: String): String? diff --git a/sdk-lib/src/main/java/cash/z/ecc/android/sdk/internal/TypesafeBackendImpl.kt b/sdk-lib/src/main/java/cash/z/ecc/android/sdk/internal/TypesafeBackendImpl.kt index b4a59a076..d2e89a752 100644 --- a/sdk-lib/src/main/java/cash/z/ecc/android/sdk/internal/TypesafeBackendImpl.kt +++ b/sdk-lib/src/main/java/cash/z/ecc/android/sdk/internal/TypesafeBackendImpl.kt @@ -244,7 +244,11 @@ internal class TypesafeBackendImpl(private val backend: Backend) : TypesafeBacke ) } - override suspend fun decryptAndStoreTransaction(tx: ByteArray) = backend.decryptAndStoreTransaction(tx) + override suspend fun decryptAndStoreTransaction( + tx: ByteArray, + minedHeight: BlockHeight? + ) = backend + .decryptAndStoreTransaction(tx, minedHeight?.value) override fun getSaplingReceiver(ua: String): String? = backend.getSaplingReceiver(ua)