From 1501f1a7d2d95eabae0754dba958b6ee98835d59 Mon Sep 17 00:00:00 2001 From: Kevin Gorham Date: Thu, 20 Dec 2018 20:44:09 -0500 Subject: [PATCH] Add data access layer for dataDb Update the scanBlocks request and integrate with the data that it generates inside dataDb --- assets/data_db_creation.sql | 39 +++ build.gradle | 10 +- .../z/wallet/sdk/dao/TransactionDaoTest.kt | 57 ++++ ...ationTest.kt => CacheDbIntegrationTest.kt} | 5 +- .../wallet/sdk/db/DerivedDbIntegrationTest.kt | 95 ++++++ .../cash/z/wallet/sdk/jni/JniConverterTest.kt | 12 +- .../java/cash/z/wallet/sdk/dao/BlockDao.kt | 26 ++ .../java/cash/z/wallet/sdk/dao/NoteDao.kt | 25 ++ .../cash/z/wallet/sdk/dao/TransactionDao.kt | 26 ++ .../cash/z/wallet/sdk/db/DerivedDataDb.kt | 25 ++ src/main/java/cash/z/wallet/sdk/vo/Block.kt | 29 ++ src/main/java/cash/z/wallet/sdk/vo/Note.kt | 80 +++++ .../java/cash/z/wallet/sdk/vo/Transaction.kt | 48 +++ src/main/rust/protos/ValueReceived.rs | 279 ++++++++++++++++++ 14 files changed, 746 insertions(+), 10 deletions(-) create mode 100644 assets/data_db_creation.sql create mode 100644 src/androidTest/java/cash/z/wallet/sdk/dao/TransactionDaoTest.kt rename src/androidTest/java/cash/z/wallet/sdk/db/{DbIntegrationTest.kt => CacheDbIntegrationTest.kt} (86%) create mode 100644 src/androidTest/java/cash/z/wallet/sdk/db/DerivedDbIntegrationTest.kt create mode 100644 src/main/java/cash/z/wallet/sdk/dao/BlockDao.kt create mode 100644 src/main/java/cash/z/wallet/sdk/dao/NoteDao.kt create mode 100644 src/main/java/cash/z/wallet/sdk/dao/TransactionDao.kt create mode 100644 src/main/java/cash/z/wallet/sdk/db/DerivedDataDb.kt create mode 100644 src/main/java/cash/z/wallet/sdk/vo/Block.kt create mode 100644 src/main/java/cash/z/wallet/sdk/vo/Note.kt create mode 100644 src/main/java/cash/z/wallet/sdk/vo/Transaction.kt create mode 100644 src/main/rust/protos/ValueReceived.rs diff --git a/assets/data_db_creation.sql b/assets/data_db_creation.sql new file mode 100644 index 00000000..37e91a11 --- /dev/null +++ b/assets/data_db_creation.sql @@ -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) + ); diff --git a/build.gradle b/build.gradle index 6bb75e2c..ce07d733 100644 --- a/build.gradle +++ b/build.gradle @@ -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() @@ -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" } @@ -60,6 +60,10 @@ android { } } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { diff --git a/src/androidTest/java/cash/z/wallet/sdk/dao/TransactionDaoTest.kt b/src/androidTest/java/cash/z/wallet/sdk/dao/TransactionDaoTest.kt new file mode 100644 index 00000000..f608e519 --- /dev/null +++ b/src/androidTest/java/cash/z/wallet/sdk/dao/TransactionDaoTest.kt @@ -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() { + 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) + } + } + +} \ No newline at end of file diff --git a/src/androidTest/java/cash/z/wallet/sdk/db/DbIntegrationTest.kt b/src/androidTest/java/cash/z/wallet/sdk/db/CacheDbIntegrationTest.kt similarity index 86% rename from src/androidTest/java/cash/z/wallet/sdk/db/DbIntegrationTest.kt rename to src/androidTest/java/cash/z/wallet/sdk/db/CacheDbIntegrationTest.kt index cdfef85d..c36af275 100644 --- a/src/androidTest/java/cash/z/wallet/sdk/db/DbIntegrationTest.kt +++ b/src/androidTest/java/cash/z/wallet/sdk/db/CacheDbIntegrationTest.kt @@ -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() @@ -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() diff --git a/src/androidTest/java/cash/z/wallet/sdk/db/DerivedDbIntegrationTest.kt b/src/androidTest/java/cash/z/wallet/sdk/db/DerivedDbIntegrationTest.kt new file mode 100644 index 00000000..550a69f4 --- /dev/null +++ b/src/androidTest/java/cash/z/wallet/sdk/db/DerivedDbIntegrationTest.kt @@ -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() + } + } +} \ No newline at end of file diff --git a/src/androidTest/java/cash/z/wallet/sdk/jni/JniConverterTest.kt b/src/androidTest/java/cash/z/wallet/sdk/jni/JniConverterTest.kt index ee12ab46..d338b4d1 100644 --- a/src/androidTest/java/cash/z/wallet/sdk/jni/JniConverterTest.kt +++ b/src/androidTest/java/cash/z/wallet/sdk/jni/JniConverterTest.kt @@ -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 @@ -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 { diff --git a/src/main/java/cash/z/wallet/sdk/dao/BlockDao.kt b/src/main/java/cash/z/wallet/sdk/dao/BlockDao.kt new file mode 100644 index 00000000..372523ee --- /dev/null +++ b/src/main/java/cash/z/wallet/sdk/dao/BlockDao.kt @@ -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) + + @Delete + fun delete(block: Block) + + @Query("SELECT COUNT(height) FROM blocks") + fun count(): Int + +} \ No newline at end of file diff --git a/src/main/java/cash/z/wallet/sdk/dao/NoteDao.kt b/src/main/java/cash/z/wallet/sdk/dao/NoteDao.kt new file mode 100644 index 00000000..c91c4b14 --- /dev/null +++ b/src/main/java/cash/z/wallet/sdk/dao/NoteDao.kt @@ -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) + + @Query("SELECT * FROM received_notes WHERE 1") + fun getAll(): List + + @Delete + fun delete(block: Note) + + @Query("SELECT COUNT(id_note) FROM received_notes") + fun count(): Int +} \ No newline at end of file diff --git a/src/main/java/cash/z/wallet/sdk/dao/TransactionDao.kt b/src/main/java/cash/z/wallet/sdk/dao/TransactionDao.kt new file mode 100644 index 00000000..1097aa07 --- /dev/null +++ b/src/main/java/cash/z/wallet/sdk/dao/TransactionDao.kt @@ -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 + + @Delete + fun delete(block: Transaction) + + @Query("SELECT COUNT(id_tx) FROM transactions") + fun count(): Int + +} \ No newline at end of file diff --git a/src/main/java/cash/z/wallet/sdk/db/DerivedDataDb.kt b/src/main/java/cash/z/wallet/sdk/db/DerivedDataDb.kt new file mode 100644 index 00000000..e88b67a5 --- /dev/null +++ b/src/main/java/cash/z/wallet/sdk/db/DerivedDataDb.kt @@ -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 +} \ No newline at end of file diff --git a/src/main/java/cash/z/wallet/sdk/vo/Block.kt b/src/main/java/cash/z/wallet/sdk/vo/Block.kt new file mode 100644 index 00000000..ac8acbca --- /dev/null +++ b/src/main/java/cash/z/wallet/sdk/vo/Block.kt @@ -0,0 +1,29 @@ +package cash.z.wallet.sdk.vo + +import androidx.room.ColumnInfo +import androidx.room.Entity + +@Entity(primaryKeys = ["height"], tableName = "blocks") +data class Block( + val height: Int, + val time: Int, + @ColumnInfo(typeAffinity = ColumnInfo.BLOB, name = "sapling_tree") + val saplingTree: ByteArray +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + return (other is Block) + && height == other.height + && time == other.time + && saplingTree.contentEquals(other.saplingTree) + } + + override fun hashCode(): Int { + var result = height + result = 31 * result + time + result = 31 * result + saplingTree.contentHashCode() + return result + } + + +} \ No newline at end of file diff --git a/src/main/java/cash/z/wallet/sdk/vo/Note.kt b/src/main/java/cash/z/wallet/sdk/vo/Note.kt new file mode 100644 index 00000000..abd3e9d0 --- /dev/null +++ b/src/main/java/cash/z/wallet/sdk/vo/Note.kt @@ -0,0 +1,80 @@ +package cash.z.wallet.sdk.vo + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey + +@Entity( + tableName = "received_notes", + primaryKeys = ["id_note"], + foreignKeys = [ForeignKey( + entity = Transaction::class, + parentColumns = ["id_tx"], + childColumns = ["tx"], + onUpdate = ForeignKey.CASCADE, + onDelete = ForeignKey.CASCADE + ), ForeignKey( + entity = Transaction::class, + parentColumns = ["id_tx"], + childColumns = ["spent"], + onUpdate = ForeignKey.CASCADE, + onDelete = ForeignKey.SET_NULL + )] +) +data class Note( + @ColumnInfo(name = "id_note") + val id: Int, + + @ColumnInfo(name = "tx") + val transaction: Int, + + @ColumnInfo(name = "output_index") + val outputIndex: Int, + + val account: Int, + val value: Int, + val spent: Int, + + @ColumnInfo(typeAffinity = ColumnInfo.BLOB) + val diversifier: ByteArray, + + @ColumnInfo(typeAffinity = ColumnInfo.BLOB) + val rcm: ByteArray, + + @ColumnInfo(typeAffinity = ColumnInfo.BLOB) + val nf: ByteArray, + + @ColumnInfo(typeAffinity = ColumnInfo.BLOB) + val memo: ByteArray? +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + + return (other is Note) + && id == other.id + && transaction == other.transaction + && outputIndex == other.outputIndex + && account == other.account + && value == other.value + && spent == other.spent + && diversifier.contentEquals(other.diversifier) + && rcm.contentEquals(other.rcm) + && nf.contentEquals(other.nf) + && ((memo == null && other.memo == null) || (memo != null && other.memo != null && memo.contentEquals(other.memo))) + } + + override fun hashCode(): Int { + var result = id + result = 31 * result + transaction + result = 31 * result + outputIndex + result = 31 * result + account + result = 31 * result + value + result = 31 * result + spent + result = 31 * result + diversifier.contentHashCode() + result = 31 * result + rcm.contentHashCode() + result = 31 * result + nf.contentHashCode() + result = 31 * result + (memo?.contentHashCode() ?: 0) + return result + } + +} \ No newline at end of file diff --git a/src/main/java/cash/z/wallet/sdk/vo/Transaction.kt b/src/main/java/cash/z/wallet/sdk/vo/Transaction.kt new file mode 100644 index 00000000..20b096b2 --- /dev/null +++ b/src/main/java/cash/z/wallet/sdk/vo/Transaction.kt @@ -0,0 +1,48 @@ +package cash.z.wallet.sdk.vo + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey +import org.jetbrains.annotations.NotNull + +@Entity( + primaryKeys = ["id_tx"], tableName = "transactions", + foreignKeys = [ForeignKey( + entity = Block::class, + parentColumns = ["height"], + childColumns = ["block"], + onDelete = ForeignKey.CASCADE + )] +) +data class Transaction( + @ColumnInfo(name = "id_tx") + val id: Int, + + @ColumnInfo(typeAffinity = ColumnInfo.BLOB, name = "txid") + @NotNull + val transactionId: ByteArray, + + val block: Int, + + @ColumnInfo(typeAffinity = ColumnInfo.BLOB) + val raw: ByteArray? +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + + return (other is Transaction) + && id == other.id + && transactionId.contentEquals(other.transactionId) + && block == other.block + && ((raw == null && other.raw == null) || (raw != null && other.raw != null && raw.contentEquals(other.raw))) + } + + override fun hashCode(): Int { + var result = id + result = 31 * result + transactionId.contentHashCode() + result = 31 * result + block + result = 31 * result + (raw?.contentHashCode() ?: 0) + return result + } + +} \ No newline at end of file diff --git a/src/main/rust/protos/ValueReceived.rs b/src/main/rust/protos/ValueReceived.rs new file mode 100644 index 00000000..8c9f5b49 --- /dev/null +++ b/src/main/rust/protos/ValueReceived.rs @@ -0,0 +1,279 @@ +// This file is generated by rust-protobuf 2.2.0. Do not edit +// @generated + +// https://github.com/Manishearth/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy)] + +#![cfg_attr(rustfmt, rustfmt_skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unsafe_code)] +#![allow(unused_imports)] +#![allow(unused_results)] + +use protobuf::Message as Message_imported_for_functions; +use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions; + +#[derive(PartialEq,Clone,Default)] +pub struct ValueReceived { + // message fields + pub blockHeight: u64, + pub txHash: ::std::vec::Vec, + pub value: u64, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl ValueReceived { + pub fn new() -> ValueReceived { + ::std::default::Default::default() + } + + // uint64 blockHeight = 1; + + pub fn clear_blockHeight(&mut self) { + self.blockHeight = 0; + } + + // Param is passed by value, moved + pub fn set_blockHeight(&mut self, v: u64) { + self.blockHeight = v; + } + + pub fn get_blockHeight(&self) -> u64 { + self.blockHeight + } + + // bytes txHash = 2; + + pub fn clear_txHash(&mut self) { + self.txHash.clear(); + } + + // Param is passed by value, moved + pub fn set_txHash(&mut self, v: ::std::vec::Vec) { + self.txHash = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_txHash(&mut self) -> &mut ::std::vec::Vec { + &mut self.txHash + } + + // Take field + pub fn take_txHash(&mut self) -> ::std::vec::Vec { + ::std::mem::replace(&mut self.txHash, ::std::vec::Vec::new()) + } + + pub fn get_txHash(&self) -> &[u8] { + &self.txHash + } + + // uint64 value = 3; + + pub fn clear_value(&mut self) { + self.value = 0; + } + + // Param is passed by value, moved + pub fn set_value(&mut self, v: u64) { + self.value = v; + } + + pub fn get_value(&self) -> u64 { + self.value + } +} + +impl ::protobuf::Message for ValueReceived { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint64()?; + self.blockHeight = tmp; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.txHash)?; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_uint64()?; + self.value = tmp; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.blockHeight != 0 { + my_size += ::protobuf::rt::value_size(1, self.blockHeight, ::protobuf::wire_format::WireTypeVarint); + } + if !self.txHash.is_empty() { + my_size += ::protobuf::rt::bytes_size(2, &self.txHash); + } + if self.value != 0 { + my_size += ::protobuf::rt::value_size(3, self.value, ::protobuf::wire_format::WireTypeVarint); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + if self.blockHeight != 0 { + os.write_uint64(1, self.blockHeight)?; + } + if !self.txHash.is_empty() { + os.write_bytes(2, &self.txHash)?; + } + if self.value != 0 { + os.write_uint64(3, self.value)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &::std::any::Any { + self as &::std::any::Any + } + fn as_any_mut(&mut self) -> &mut ::std::any::Any { + self as &mut ::std::any::Any + } + fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> ValueReceived { + ValueReceived::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, + }; + unsafe { + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint64>( + "blockHeight", + |m: &ValueReceived| { &m.blockHeight }, + |m: &mut ValueReceived| { &mut m.blockHeight }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( + "txHash", + |m: &ValueReceived| { &m.txHash }, + |m: &mut ValueReceived| { &mut m.txHash }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint64>( + "value", + |m: &ValueReceived| { &m.value }, + |m: &mut ValueReceived| { &mut m.value }, + )); + ::protobuf::reflect::MessageDescriptor::new::( + "ValueReceived", + fields, + file_descriptor_proto() + ) + }) + } + } + + fn default_instance() -> &'static ValueReceived { + static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ValueReceived, + }; + unsafe { + instance.get(ValueReceived::new) + } + } +} + +impl ::protobuf::Clear for ValueReceived { + fn clear(&mut self) { + self.clear_blockHeight(); + self.clear_txHash(); + self.clear_value(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for ValueReceived { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ValueReceived { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + ::protobuf::reflect::ProtobufValueRef::Message(self) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x13ValueReceived.proto\x12\x17cash.z.wallet.sdk.proto\"O\n\rValueRece\ + ived\x12\x17\n\x0bblockHeight\x18\x01\x20\x01(\x04B\x02\x18\0\x12\x12\n\ + \x06txHash\x18\x02\x20\x01(\x0cB\x02\x18\0\x12\x11\n\x05value\x18\x03\ + \x20\x01(\x04B\x02\x18\0B\0b\x06proto3\ +"; + +static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy { + lock: ::protobuf::lazy::ONCE_INIT, + ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto, +}; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + unsafe { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) + } +}