[#477] Fixes for Zatoshi object

This commit is contained in:
Carter Jernigan 2022-07-07 08:52:07 -04:00 committed by Carter Jernigan
parent 1ac72feae3
commit a1cc8f0b69
17 changed files with 60 additions and 52 deletions

View File

@ -7,6 +7,8 @@ Various APIs used `Long` value to represent Zatoshi currency amounts. Those API
`WalletBalance` no longer has uninitialized default values. This means that `Synchronizer` fields that expose a WalletBalance now use `null` to signal an uninitialized value. Specifically this means `Synchronizer.orchardBalances`, `Synchronzier.saplingBalances`, and `Synchronizer.transparentBalances` have nullable values now.
`WalletBalance` has been moved from the package `cash.z.ecc.android.sdk.type` to `cash.z.ecc.android.sdk.model`
`ZcashSdk.ZATOSHI_PER_ZEC` has been moved to `Zatoshi.ZATOSHI_PER_ZEC`.
`ZcashSdk.MINERS_FEE_ZATOSHI` has been renamed to `ZcashSdk.MINERS_FEE` and the type has changed from `Long` to `Zatoshi`.

View File

@ -10,9 +10,9 @@ import cash.z.ecc.android.sdk.db.entity.isPending
import cash.z.ecc.android.sdk.internal.Twig
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.twig
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob

View File

@ -14,8 +14,8 @@ import cash.z.ecc.android.sdk.demoapp.ext.requireApplicationContext
import cash.z.ecc.android.sdk.demoapp.util.fromResources
import cash.z.ecc.android.sdk.ext.collectWith
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.runBlocking

View File

@ -29,8 +29,8 @@ import cash.z.ecc.android.sdk.ext.convertZecToZatoshi
import cash.z.ecc.android.sdk.ext.toZecString
import cash.z.ecc.android.sdk.internal.Twig
import cash.z.ecc.android.sdk.internal.twig
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.runBlocking

View File

@ -10,9 +10,9 @@ import cash.z.ecc.android.sdk.db.entity.isPending
import cash.z.ecc.android.sdk.internal.Twig
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.twig
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob

View File

@ -46,13 +46,13 @@ import cash.z.ecc.android.sdk.internal.transaction.TransactionRepository
import cash.z.ecc.android.sdk.internal.transaction.WalletTransactionEncoder
import cash.z.ecc.android.sdk.internal.twig
import cash.z.ecc.android.sdk.internal.twigTask
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.AddressType
import cash.z.ecc.android.sdk.type.AddressType.Shielded
import cash.z.ecc.android.sdk.type.AddressType.Transparent
import cash.z.ecc.android.sdk.type.ConsensusMatchType
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.type.ZcashNetwork
import cash.z.wallet.sdk.rpc.Service
import io.grpc.ManagedChannel

View File

@ -4,10 +4,10 @@ import cash.z.ecc.android.sdk.block.CompactBlockProcessor
import cash.z.ecc.android.sdk.db.entity.ConfirmedTransaction
import cash.z.ecc.android.sdk.db.entity.PendingTransaction
import cash.z.ecc.android.sdk.ext.ZcashSdk
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.type.AddressType
import cash.z.ecc.android.sdk.type.ConsensusMatchType
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.type.ZcashNetwork
import cash.z.wallet.sdk.rpc.Service
import kotlinx.coroutines.CoroutineScope

View File

@ -39,7 +39,7 @@ import cash.z.ecc.android.sdk.internal.twig
import cash.z.ecc.android.sdk.internal.twigTask
import cash.z.ecc.android.sdk.jni.RustBackend
import cash.z.ecc.android.sdk.jni.RustBackendWelding
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.wallet.sdk.rpc.Service
import io.grpc.StatusRuntimeException
import kotlinx.coroutines.Dispatchers

View File

@ -96,6 +96,10 @@ data class PendingTransactionEntity(
@ColumnInfo(typeAffinity = ColumnInfo.BLOB)
override val rawTransactionId: ByteArray? = byteArrayOf()
) : PendingTransaction {
val valueZatoshi: Zatoshi
get() = Zatoshi(value)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is PendingTransactionEntity) return false

View File

@ -115,7 +115,7 @@ class PersistentTransactionManager(
twig("beginning to encode transaction with : $encoder")
val encodedTx = encoder.createTransaction(
spendingKey,
tx.value,
tx.valueZatoshi,
tx.toAddress,
tx.memo,
tx.accountIndex

View File

@ -1,6 +1,7 @@
package cash.z.ecc.android.sdk.internal.transaction
import cash.z.ecc.android.sdk.db.entity.EncodedTransaction
import cash.z.ecc.android.sdk.model.Zatoshi
interface TransactionEncoder {
/**
@ -18,7 +19,7 @@ interface TransactionEncoder {
*/
suspend fun createTransaction(
spendingKey: String,
zatoshi: Long,
amount: Zatoshi,
toAddress: String,
memo: ByteArray? = byteArrayOf(),
fromAccountIndex: Int = 0

View File

@ -8,6 +8,7 @@ import cash.z.ecc.android.sdk.internal.twig
import cash.z.ecc.android.sdk.internal.twigTask
import cash.z.ecc.android.sdk.jni.RustBackend
import cash.z.ecc.android.sdk.jni.RustBackendWelding
import cash.z.ecc.android.sdk.model.Zatoshi
/**
* Class responsible for encoding a transaction in a consistent way. This bridges the gap by
@ -18,7 +19,7 @@ import cash.z.ecc.android.sdk.jni.RustBackendWelding
* @property repository the repository that stores information about the transactions being created
* such as the raw bytes and raw txId.
*/
class WalletTransactionEncoder(
internal class WalletTransactionEncoder(
private val rustBackend: RustBackendWelding,
private val repository: TransactionRepository
) : TransactionEncoder {
@ -29,7 +30,7 @@ class WalletTransactionEncoder(
* exception ourselves (rather than using double-bangs for things).
*
* @param spendingKey the key associated with the notes that will be spent.
* @param zatoshi the amount of zatoshi to send.
* @param amount the amount of zatoshi to send.
* @param toAddress the recipient's address.
* @param memo the optional memo to include as part of the transaction.
* @param fromAccountIndex the optional account id to use. By default, the 1st account is used.
@ -38,12 +39,12 @@ class WalletTransactionEncoder(
*/
override suspend fun createTransaction(
spendingKey: String,
zatoshi: Long,
amount: Zatoshi,
toAddress: String,
memo: ByteArray?,
fromAccountIndex: Int
): EncodedTransaction {
val transactionId = createSpend(spendingKey, zatoshi, toAddress, memo)
val transactionId = createSpend(spendingKey, amount, toAddress, memo)
return repository.findEncodedTransactionById(transactionId)
?: throw TransactionEncoderException.TransactionNotFoundException(transactionId)
}
@ -93,7 +94,7 @@ class WalletTransactionEncoder(
* the result in the database. On average, this call takes over 10 seconds.
*
* @param spendingKey the key associated with the notes that will be spent.
* @param zatoshi the amount of zatoshi to send.
* @param amount the amount of zatoshi to send.
* @param toAddress the recipient's address.
* @param memo the optional memo to include as part of the transaction.
* @param fromAccountIndex the optional account id to use. By default, the 1st account is used.
@ -103,13 +104,13 @@ class WalletTransactionEncoder(
*/
private suspend fun createSpend(
spendingKey: String,
zatoshi: Long,
amount: Zatoshi,
toAddress: String,
memo: ByteArray? = byteArrayOf(),
fromAccountIndex: Int = 0
): Long {
return twigTask(
"creating transaction to spend $zatoshi zatoshi to" +
"creating transaction to spend $amount zatoshi to" +
" ${toAddress.masked()} with memo $memo"
) {
try {
@ -121,7 +122,7 @@ class WalletTransactionEncoder(
fromAccountIndex,
spendingKey,
toAddress,
zatoshi,
amount.value,
memo
)
} catch (t: Throwable) {

View File

@ -6,10 +6,10 @@ import cash.z.ecc.android.sdk.ext.ZcashSdk.SPEND_PARAM_FILE_NAME
import cash.z.ecc.android.sdk.internal.SdkDispatchers
import cash.z.ecc.android.sdk.internal.ext.deleteSuspend
import cash.z.ecc.android.sdk.internal.twig
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.withContext
import java.io.File

View File

@ -1,8 +1,8 @@
package cash.z.ecc.android.sdk.jni
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.type.ZcashNetwork
/**

View File

@ -0,0 +1,28 @@
package cash.z.ecc.android.sdk.model
/**
* Data structure to hold the total and available balance of the wallet. This is what is
* received on the balance channel.
*
* @param total the total balance, ignoring funds that cannot be used.
* @param available the amount of funds that are available for use. Typical reasons that funds
* may be unavailable include fairly new transactions that do not have enough confirmations or
* notes that are tied up because we are awaiting change from a transaction. When a note has
* been spent, its change cannot be used until there are enough confirmations.
*/
data class WalletBalance(
val total: Zatoshi,
val available: Zatoshi
) {
init {
require(total.value >= available.value) { "Wallet total balance must be >= available balance" }
}
val pending = total - available
operator fun plus(other: WalletBalance): WalletBalance =
WalletBalance(
total + other.total,
available + other.available
)
}

View File

@ -1,34 +1,5 @@
package cash.z.ecc.android.sdk.type
import cash.z.ecc.android.sdk.model.Zatoshi
/**
* Data structure to hold the total and available balance of the wallet. This is what is
* received on the balance channel.
*
* @param total the total balance, ignoring funds that cannot be used.
* @param available the amount of funds that are available for use. Typical reasons that funds
* may be unavailable include fairly new transactions that do not have enough confirmations or
* notes that are tied up because we are awaiting change from a transaction. When a note has
* been spent, its change cannot be used until there are enough confirmations.
*/
data class WalletBalance(
val total: Zatoshi,
val available: Zatoshi
) {
init {
require(total.value >= available.value) { "Wallet total balance must be >= available balance" }
}
val pending = total - available
operator fun plus(other: WalletBalance): WalletBalance =
WalletBalance(
total + other.total,
available + other.available
)
}
/**
* Model object for holding a wallet birthday.
*

View File

@ -1,5 +1,6 @@
package cash.z.ecc.android.sdk.ext
import cash.z.ecc.android.sdk.model.Zatoshi
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import java.math.BigDecimal
@ -9,7 +10,7 @@ internal class ConversionsTest {
@Test
fun `default right padding is 6`() {
assertEquals(1.13.toZec(6), 113000000L.convertZatoshiToZec())
assertEquals(1.13.toZec(6), Zatoshi(113000000L).convertZatoshiToZec())
assertEquals(1.13.toZec(6), 1.13.toZec())
}
@ -21,12 +22,12 @@ internal class ConversionsTest {
@Test
fun `toZecString defaults to 6 digits`() {
assertEquals("1.123457", 112345678L.convertZatoshiToZecString())
assertEquals("1.123457", Zatoshi(112345678L).convertZatoshiToZecString())
}
@Test
fun `toZecString uses banker's rounding`() {
assertEquals("1.123456", 112345650L.convertZatoshiToZecString())
assertEquals("1.123456", Zatoshi(112345650L).convertZatoshiToZecString())
}
@Test
@ -72,7 +73,7 @@ internal class ConversionsTest {
@Test
fun `toZecString zatoshi converts`() {
assertEquals("1.123456", 112345650L.convertZatoshiToZecString(6, 0))
assertEquals("1.123456", Zatoshi(112345650L).convertZatoshiToZecString(6, 0))
}
@Test