Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate with lightwalletd and librustzcash #16

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c99f9a3
Add data access layer for dataDb
gmale Dec 21, 2018
2c0966a
Create synchronizer and add layer of business logic onto the data layer
gmale Jan 3, 2019
986ee50
Switch to JUnit 5
gmale Jan 4, 2019
5915ad3
Create CompactBlockDownloader, iterate on business logic using new JU…
gmale Jan 13, 2019
9448f43
Integrate with dataDb init commands and grpc service updates.
gmale Jan 16, 2019
13642d6
Create CompactBlockProcessor and refine responsibilities of collabora…
gmale Jan 23, 2019
84b8756
Create ActiveTransactionManager to monitor active transactions
gmale Feb 3, 2019
e668946
Iterate and refine send and active transaction behavior
gmale Feb 5, 2019
bfdd093
Create mock synchronizer to help with driving the UI.
gmale Feb 14, 2019
21f09fa
Fix bugs
gmale Feb 14, 2019
1892e4d
Add conversion logic and extensions for consistency and correctness
gmale Feb 18, 2019
913ecb4
Twig: Refactor to be much more useful.
gmale Feb 19, 2019
37c9cf7
Add additional logging to mock synchronizer
gmale Feb 19, 2019
df9f020
Add address information to notes query and other cleanup
gmale Feb 19, 2019
c5e5941
Prevent change from being returned in transaction queries
gmale Feb 23, 2019
09de20c
Remove unused things and document limits of Junit 5 usage
gmale Feb 24, 2019
56fada2
Improve logic and behavior during app startup.
gmale Feb 24, 2019
ed5e9c0
Add a layer of logic for bubbling up errors
gmale Feb 24, 2019
d38c348
Update the logic for determining balance
gmale Feb 26, 2019
c7d85f2
Cleanup
gmale Mar 12, 2019
764455d
Clean up data API
gmale Mar 13, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 52 additions & 12 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ buildscript {
'targetSdkVersion': 28
]
ext.versions = [
'architectureComponents': '2.0.0',
'grpc':'1.17.1',
'kotlin': '1.3.10',
'architectureComponents': '2.0.0'
'coroutines': '1.1.0'
]
repositories {
google()
Expand All @@ -17,6 +19,7 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
classpath "com.github.ben-manes:gradle-versions-plugin:0.20.0"
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.7"
}
}

Expand All @@ -25,6 +28,7 @@ apply plugin: 'com.android.library'
apply plugin: "kotlin-android-extensions"
apply plugin: "kotlin-android"
apply plugin: 'kotlin-kapt'
apply plugin: 'com.google.protobuf'
apply plugin: 'com.github.ben-manes.versions'
apply plugin: 'com.github.dcendents.android-maven'

Expand All @@ -34,6 +38,7 @@ version = '1.2.4'
repositories {
google()
jcenter()
mavenCentral()
}

android {
Expand All @@ -42,9 +47,10 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode = 1_02_03
versionName = "1.2.3"
versionCode = 1_03_00
versionName = "1.3.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled false
}

buildTypes {
Expand All @@ -56,7 +62,10 @@ android {
sourceSets {
main {
java {
srcDirs "build/generated/source/wire"
srcDirs "build/generated/source/grpc"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be src/generated/source/grpc?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as far as I can tell, it is.

}
proto {
srcDir 'src/main/proto'
}
}
}
Expand All @@ -66,29 +75,60 @@ android {
}
}

clean {
delete "$project.projectDir/src/generated/source/grpc"
}


protobuf {
generatedFilesBaseDir = "$projectDir/src/generated/source/grpc"
protoc { artifact = 'com.google.protobuf:protoc:3.6.1' }
plugins {
javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" }
grpc { artifact = "io.grpc:protoc-gen-grpc-java:${versions.grpc}" }
}
generateProtoTasks {
all().each { task ->
task.plugins {
javalite {}
grpc { // Options added to --grpc_out
option 'lite' }
}
}
}
}

dependencies {
// Square
api "com.squareup.wire:wire-runtime:2.2.0"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.multidex:multidex:2.0.1'

// Architecture components
implementation "androidx.lifecycle:lifecycle-runtime:${versions.architectureComponents}"
implementation "androidx.lifecycle:lifecycle-extensions:${versions.architectureComponents}"
implementation "androidx.room:room-runtime:${versions.architectureComponents}"
implementation "androidx.room:room-common:${versions.architectureComponents}"
kapt "androidx.lifecycle:lifecycle-compiler:${versions.architectureComponents}"
kapt "androidx.room:room-compiler:${versions.architectureComponents}"

// Other
// kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${versions.kotlin}"
implementation "com.android.support:appcompat-v7:28.0.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.coroutines}"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${versions.coroutines}"

// grpc-java
implementation "io.grpc:grpc-okhttp:${versions.grpc}"
implementation "io.grpc:grpc-protobuf-lite:${versions.grpc}"
implementation "io.grpc:grpc-stub:${versions.grpc}"
implementation 'javax.annotation:javax.annotation-api:1.2'

// Tests
testImplementation "junit:junit:4.12"
androidTestImplementation "androidx.test:runner:1.1.0"
androidTestImplementation "androidx.test.espresso:espresso-core:3.1.0"
androidTestImplementation "androidx.test:core:1.0.0"
androidTestImplementation "androidx.test:runner:1.1.1"
androidTestImplementation "androidx.test.espresso:espresso-core:3.1.1"
androidTestImplementation "androidx.test:core:1.1.0"
androidTestImplementation "androidx.arch.core:core-testing:${versions.architectureComponents}"
}


preBuild.dependsOn generateProtobufClasses
preBuild.dependsOn includeDirBugFix
preBuild.dependsOn copyAllJniLibs
83 changes: 56 additions & 27 deletions custom-tasks.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
def protoSrcDir = "src/main/proto"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: I've put zero energy into cleaning this file because it will be deleted once #15 is merged.

def protoDestDir = "build/generated/source/wire"
//def protoSrcDir = "src/main/proto"
//def protoDestDir = "build/generated/source/grpc"
def protoIncludeDir = "build/extracted-include-protos/main"
def jniSrcDir = "src/main/rust"
def jniDestDir = "build/rust/target"

Expand All @@ -11,36 +12,64 @@ def libArm64Dir = "src/main/jniLibs/arm64-v8a"
def libArmeabiFile = "build/rust/target/armv7-linux-androideabi/release/$libFile"
def libArmeabiDir = "src/main/jniLibs/armeabi-v7a"

buildscript {
dependencies {
classpath("com.squareup.wire:wire-compiler:2.2.0")
}
repositories {
mavenCentral()
}
}
//buildscript {
// dependencies {
// classpath("com.squareup.wire:wire-compiler:2.2.0")
// }
// repositories {
// mavenCentral()
// }
//}

tasks.register("generateProtobufClasses") {
doFirst {
println("**** CREATING PROTOS ****")
delete(protoDestDir)
mkdir(protoDestDir)
}
description = "Generate Java classes from protocol buffer (.proto) schema files for use with Square's Wire library"
//tasks.register("generateGrpcClasses") {
// doFirst {
// println("**** CREATING PROTOS ****")
// delete(protoDestDir)
// mkdir(protoDestDir)
// }
// description = "Generate Java classes from protocol buffer (.proto) schema files for use with grpc"
//
// fileTree(dir: protoSrcDir, include: '**/*.proto').each { File file ->
// doLast {
// javaexec {
// main = "com.squareup.wire.WireCompiler"
// classpath = buildscript.configurations.classpath
// args = ["--proto_path=$protoSrcDir", "--java_out=$protoDestDir", file.path]
// }
// }
// }
// inputs.files(fileTree(dir: protoSrcDir, include: '**/*.proto'))
// outputs.files(fileTree(dir: protoDestDir, include: '**'))
//}

fileTree(dir: protoSrcDir, include: '**/*.proto').each { File file ->
doLast {
javaexec {
main = "com.squareup.wire.WireCompiler"
classpath = buildscript.configurations.classpath
args = ["--proto_path=$protoSrcDir", "--java_out=$protoDestDir", file.path]
}
}
//tasks.register("generateProtobufClasses") {
// doFirst {
// println("**** CREATING PROTOS ****")
// delete(protoDestDir)
// mkdir(protoDestDir)
// }
// description = "Generate Java classes from protocol buffer (.proto) schema files for use with Square's Wire library"
//
// fileTree(dir: protoSrcDir, include: '**/*.proto').each { File file ->
// doLast {
// javaexec {
// main = "com.squareup.wire.WireCompiler"
// classpath = buildscript.configurations.classpath
// args = ["--proto_path=$protoSrcDir", "--java_out=$protoDestDir", file.path]
// }
// }
// }
// inputs.files(fileTree(dir: protoSrcDir, include: '**/*.proto'))
// outputs.files(fileTree(dir: protoDestDir, include: '**'))
//}
tasks.register("includeDirBugFix") {
doFirst {
mkdir(protoIncludeDir)
}
inputs.files(fileTree(dir: protoSrcDir, include: '**/*.proto'))
outputs.files(fileTree(dir: protoDestDir, include: '**'))
}

// TODO: run these in paralell with the worker API: https://guides.gradle.org/using-the-worker-api/
// note: this will require modifying the build script and having 3 separate calls
tasks.register("generateJniLibs") {
doFirst {
println("**** CREATING JNI LIBS ****")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package cash.z.wallet.sdk.data

import android.util.Log
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import kotlinx.coroutines.*
import org.junit.AfterClass
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.BeforeClass
import org.junit.Rule
import org.junit.Test
import rpc.CompactFormats

class CompactBlockDownloaderTest {
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()

@Test
fun testSynchronizerExists() {
assertNotNull(downloader)
}

@Test
fun testBlocks() = runBlocking {
msg("about to receive (is the channel Closed? ${downloader.blocks().isClosedForReceive})")
val result = downloader.blocks().receive()
msg("donezo")
assertTrue(printFailure(result), result.isSuccess)
}

private fun printFailure(result: Result<CompactFormats.CompactBlock>): String {
return if (result.isFailure) "result failed due to: ${result.exceptionOrNull()!!.let { "$it caused by: ${it.cause}" }}}"
else "success"
}

@Test
fun testBlockHeight() = runBlocking {
delay(200)
val result = downloader.blocks().receive()
assertTrue(printFailure(result), result.isSuccess)
assertTrue("Unexpected height value", result.getOrThrow().height > 300000)
}

companion object {
val job = Job()
val testScope = CoroutineScope(Dispatchers.IO + job)
val downloader = CompactBlockDownloader(testScope)

@BeforeClass
@JvmStatic
fun setup() {
downloader.start()
}

@AfterClass
@JvmStatic
fun close() {
downloader.stop()
job.cancel()
}

fun msg(message: String) {
Log.e("DBUG", "[${Thread.currentThread().name}] $message")
}
}
}
56 changes: 56 additions & 0 deletions src/androidTest/java/cash/z/wallet/sdk/data/SynchronizerTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package cash.z.wallet.sdk.data

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.test.core.app.ApplicationProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import org.junit.AfterClass
import org.junit.Assert.assertNotNull
import org.junit.BeforeClass
import org.junit.Rule
import org.junit.Test
import rpc.CompactFormats

class SynchronizerTest {
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()

@Test
fun testSynchronizerExists() {
assertNotNull(synchronizer)
}

@Test
fun testBlockSaving() {
// synchronizer.saveBlocks()
}
@Test
fun testBlockScanning() {
Thread.sleep(180000L)
}
private fun printFailure(result: Result<CompactFormats.CompactBlock>): String {
return if (result.isFailure) "result failed due to: ${result.exceptionOrNull()!!.let { "$it caused by: ${it.cause}" }}}"
else "success"
}

companion object {
val job = Job()
val testScope = CoroutineScope(Dispatchers.IO + job)
val synchronizer = Synchronizer(ApplicationProvider.getApplicationContext(), testScope)

@BeforeClass
@JvmStatic
fun setup() {
synchronizer.start()
}

@AfterClass
@JvmStatic
fun close() {
synchronizer.stop()
testScope.cancel()
}
}
}
Loading