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
39 changes: 39 additions & 0 deletions assets/data_db_creation.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
CREATE TABLE IF NOT EXISTS blocks (
height INTEGER PRIMARY KEY,
time INTEGER,
sapling_tree BLOB
);

CREATE TABLE IF NOT EXISTS transactions (
id_tx INTEGER PRIMARY KEY,
txid BLOB NOT NULL UNIQUE,
block INTEGER,
raw BLOB,
FOREIGN KEY (block) REFERENCES blocks(height)
);

CREATE TABLE IF NOT EXISTS received_notes (
id_note INTEGER PRIMARY KEY,
tx INTEGER NOT NULL,
output_index INTEGER NOT NULL,
account INTEGER NOT NULL,
diversifier BLOB NOT NULL,
value INTEGER NOT NULL,
rcm BLOB NOT NULL,
nf BLOB NOT NULL UNIQUE,
memo BLOB,
spent INTEGER,
FOREIGN KEY (tx) REFERENCES transactions(id_tx),
FOREIGN KEY (spent) REFERENCES transactions(id_tx),
CONSTRAINT tx_output UNIQUE (tx, output_index)
);

CREATE TABLE IF NOT EXISTS sapling_witnesses (
id_witness INTEGER PRIMARY KEY,
note INTEGER NOT NULL,
block INTEGER NOT NULL,
witness BLOB NOT NULL,
FOREIGN KEY (note) REFERENCES received_notes(id_note),
FOREIGN KEY (block) REFERENCES blocks(height),
CONSTRAINT witness_height UNIQUE (note, block)
);
10 changes: 7 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ apply plugin: 'com.github.ben-manes.versions'
apply plugin: 'com.github.dcendents.android-maven'

group = 'cash.z.android.wallet'
version = '1.2.0'
version = '1.2.4'

repositories {
google()
Expand All @@ -42,8 +42,8 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode = 1_02_00
versionName = "1.2.0"
versionCode = 1_02_03
versionName = "1.2.3"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

Expand All @@ -60,6 +60,10 @@ android {
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {
Expand Down
57 changes: 57 additions & 0 deletions src/androidTest/java/cash/z/wallet/sdk/dao/TransactionDaoTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package cash.z.wallet.sdk.dao

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.room.Room
import androidx.test.platform.app.InstrumentationRegistry
import cash.z.wallet.sdk.db.CompactBlockDb
import cash.z.wallet.sdk.db.DerivedDataDb
import cash.z.wallet.sdk.vo.CompactBlock
import cash.z.wallet.sdk.vo.Transaction
import org.junit.*
import org.junit.Assert.*

class TransactionDaoTest {

@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()

private lateinit var dao: TransactionDao
private lateinit var db: DerivedDataDb

@Before
fun initDb() {
db = Room.inMemoryDatabaseBuilder(
InstrumentationRegistry.getInstrumentation().context,
DerivedDataDb::class.java
)
.build()
.apply { dao = transactionDao() }
}

@After
fun close() {
db.close()
}

@Test
fun testDbExists() {
assertNotNull(db)
}

@Test
fun testDaoExists() {
assertNotNull(dao)
}

@Test
fun testDaoInsert() {
Copy link
Contributor

Choose a reason for hiding this comment

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

This test suggests that inserts into the data db from the Android side are okay. Add a comment that this is only for testing purposes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 81141d9

Transaction(4, "sample".toByteArray(), 356418, null).let { transaction ->
dao.insert(transaction)
val result = dao.findById(transaction.id)
assertEquals(transaction.id, result?.id)
assertTrue(transaction.transactionId.contentEquals(result!!.transactionId))
dao.delete(transaction)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import cash.z.wallet.sdk.vo.CompactBlock
import org.junit.*
import org.junit.Assert.*

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

Expand Down Expand Up @@ -39,7 +39,8 @@ class DbIntegrationTest {
fun setup() {
// TODO: put this database in the assets directory and open it from there via .openHelperFactory(new AssetSQLiteOpenHelperFactory()) seen here https://github.com/albertogiunta/sqliteAsset
db = Room
.databaseBuilder(ApplicationProvider.getApplicationContext(), CompactBlockDb::class.java, "compact-blocks.db")
.databaseBuilder(ApplicationProvider.getApplicationContext(), CompactBlockDb::class.java, "dummy-cache.db")
// .databaseBuilder(ApplicationProvider.getApplicationContext(), CompactBlockDb::class.java, "compact-blocks.db")
.setJournalMode(RoomDatabase.JournalMode.TRUNCATE)
.fallbackToDestructiveMigration()
.build()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package cash.z.wallet.sdk.db

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.test.core.app.ApplicationProvider
import cash.z.wallet.sdk.dao.BlockDao
import cash.z.wallet.sdk.dao.CompactBlockDao
import cash.z.wallet.sdk.dao.NoteDao
import cash.z.wallet.sdk.dao.TransactionDao
import cash.z.wallet.sdk.vo.CompactBlock
import org.junit.*
import org.junit.Assert.*

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

@Test
fun testDbExists() {
assertNotNull(db)
}

@Test
fun testDaoExists_Transaction() {
assertNotNull(transactions)
}

@Test
fun testDaoExists_Block() {
assertNotNull(blocks)
}

@Test
fun testDaoExists_Note() {
assertNotNull(notes)
}

@Test
fun testCount_Transaction() {
assertEquals(5, transactions.count())
}

@Test
fun testCount_Block() {
assertEquals(80101, blocks.count())
}

@Test
fun testCount_Note() {
assertEquals(5, notes.count())
}
@Test
fun testTransactionDaoPrepopulated() {
val tran = transactions.findById(1)

assertEquals(343987, tran?.block)
}

@Test
fun testBlockDaoPrepopulated() {
val tran = blocks.findById(1)?.apply {
assertEquals(343987, this.height)
}
}

companion object {
private lateinit var transactions: TransactionDao
private lateinit var blocks: BlockDao
private lateinit var notes: NoteDao
private lateinit var db: DerivedDataDb

@BeforeClass
@JvmStatic
fun setup() {
// TODO: put this database in the assets directory and open it from there via .openHelperFactory(new AssetSQLiteOpenHelperFactory()) seen here https://github.com/albertogiunta/sqliteAsset
db = Room
.databaseBuilder(ApplicationProvider.getApplicationContext(), DerivedDataDb::class.java, "dummy-data2.db")
.setJournalMode(RoomDatabase.JournalMode.TRUNCATE)
.fallbackToDestructiveMigration()
.build()
.apply {
transactions = transactionDao()
blocks = blockDao()
notes = noteDao()
}
}

@AfterClass
@JvmStatic
fun close() {
db.close()
}
}
}
12 changes: 7 additions & 5 deletions src/androidTest/java/cash/z/wallet/sdk/jni/JniConverterTest.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cash.z.wallet.sdk.jni

import android.text.format.DateUtils
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.BeforeClass
Expand All @@ -23,12 +24,13 @@ class JniConverterTest {
fun testScanBlocks() {
// note: for this to work, the db file below must be uploaded to the device. Eventually, this test will be self-contained and remove that requirement.
val result = converter.scanBlocks(
"/data/user/0/cash.z.wallet.sdk.test/databases/compact-block.db",
343900,
344855,
"dummyseed".toByteArray()
"/data/user/0/cash.z.wallet.sdk.test/databases/dummy-cache.db",
"/data/user/0/cash.z.wallet.sdk.test/databases/data.db",
"dummyseed".toByteArray(),
343900
)
assertEquals("Invalid number of results", 2, result.size)
// Thread.sleep(15 * DateUtils.MINUTE_IN_MILLIS)
assertEquals("Invalid number of results", 2, 3)
}

companion object {
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/cash/z/wallet/sdk/dao/BlockDao.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cash.z.wallet.sdk.dao

import androidx.room.*
import cash.z.wallet.sdk.vo.Block
import androidx.lifecycle.LiveData



@Dao
interface BlockDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(block: Block)

@Query("SELECT * FROM blocks WHERE height = :height")
fun findById(height: Int): Block?

@Query("DELETE FROM blocks WHERE height = :height")
fun deleteById(height: Int)
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto re: modifications to data DB from Android side.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 81141d9


@Delete
fun delete(block: Block)

@Query("SELECT COUNT(height) FROM blocks")
fun count(): Int

}
25 changes: 25 additions & 0 deletions src/main/java/cash/z/wallet/sdk/dao/NoteDao.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cash.z.wallet.sdk.dao

import androidx.room.*
import cash.z.wallet.sdk.vo.Note

@Dao
interface NoteDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(block: Note)

@Query("SELECT * FROM received_notes WHERE id_note = :id")
fun findById(id: Int): Note?

@Query("DELETE FROM received_notes WHERE id_note = :id")
fun deleteById(id: Int)
Copy link
Contributor

Choose a reason for hiding this comment

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

This allows modifications to the data DB from the Android side. Do we want this as part of the public API? What is it used for?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 81141d9


@Query("SELECT * FROM received_notes WHERE 1")
fun getAll(): List<Note>

@Delete
fun delete(block: Note)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know how @Delete works, but I assume it does some kind of matching. This allows modifications to the data DB from the Android side.

Also, s/block/note

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 81141d9


@Query("SELECT COUNT(id_note) FROM received_notes")
fun count(): Int
}
26 changes: 26 additions & 0 deletions src/main/java/cash/z/wallet/sdk/dao/TransactionDao.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cash.z.wallet.sdk.dao

import androidx.room.*
import cash.z.wallet.sdk.vo.Transaction

@Dao
interface TransactionDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(block: Transaction)

@Query("SELECT * FROM transactions WHERE id_tx = :id")
fun findById(id: Int): Transaction?

@Query("DELETE FROM transactions WHERE id_tx = :id")
fun deleteById(id: Int)

@Query("SELECT * FROM transactions WHERE 1")
fun getAll(): List<Transaction>

@Delete
fun delete(block: Transaction)

@Query("SELECT COUNT(id_tx) FROM transactions")
fun count(): Int

}
25 changes: 25 additions & 0 deletions src/main/java/cash/z/wallet/sdk/db/DerivedDataDb.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cash.z.wallet.sdk.db

import androidx.room.Database
import androidx.room.RoomDatabase
import cash.z.wallet.sdk.dao.BlockDao
import cash.z.wallet.sdk.dao.NoteDao
import cash.z.wallet.sdk.dao.TransactionDao
import cash.z.wallet.sdk.vo.Block
import cash.z.wallet.sdk.vo.Note
import cash.z.wallet.sdk.vo.Transaction

@Database(
entities = [
Transaction::class,
Block::class,
Note::class
],
version = 1,
exportSchema = false
)
abstract class DerivedDataDb : RoomDatabase() {
abstract fun transactionDao(): TransactionDao
abstract fun noteDao(): NoteDao
abstract fun blockDao(): BlockDao
}
Loading