backend-lib: Expose `AccountBalance` fields across the FFI

* backend-lib: Expose `AccountBalance` fields across the FFI

* Update related fixture class

---------

Co-authored-by: Honza <rychnovsky.honza@gmail.com>
This commit is contained in:
str4d 2024-02-05 15:16:13 +00:00 committed by GitHub
parent 394ddefb16
commit b617eb1bb3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 66 additions and 26 deletions

View File

@ -6,33 +6,59 @@ import androidx.annotation.Keep
* Serves as cross layer (Kotlin, Rust) communication class.
*
* @param account the account ID
* @param saplingTotalBalance The total account balance in the Sapling pool,
* including unconfirmed funds.
* @param saplingVerifiedBalance The verified account balance in the Sapling pool.
* @param orchardTotalBalance The total account balance in the Orchard pool,
* including unconfirmed funds.
* @param saplingChangePending The value in the account of Sapling change notes that do
* not yet have sufficient confirmations to be spendable.
* @param saplingValuePending The value in the account of all remaining received Sapling
* notes that either do not have sufficient confirmations to be spendable, or for
* which witnesses cannot yet be constructed without additional scanning.
* @param orchardVerifiedBalance The verified account balance in the Orchard pool.
* @param orchardChangePending The value in the account of Orchard change notes that do
* not yet have sufficient confirmations to be spendable.
* @param orchardValuePending The value in the account of all remaining received Orchard
* notes that either do not have sufficient confirmations to be spendable, or for
* which witnesses cannot yet be constructed without additional scanning.
* @param unshieldedBalance The total account balance in the transparent pool,
* including unconfirmed funds, that must be shielded before use.
* @throws IllegalArgumentException if the values are inconsistent.
*/
@Keep
@Suppress("LongParameterList")
class JniAccountBalance(
val account: Int,
val saplingTotalBalance: Long,
val saplingVerifiedBalance: Long,
val orchardTotalBalance: Long,
val saplingChangePending: Long,
val saplingValuePending: Long,
val orchardVerifiedBalance: Long,
val orchardChangePending: Long,
val orchardValuePending: Long,
val unshieldedBalance: Long,
) {
init {
require(saplingTotalBalance >= saplingVerifiedBalance) {
"Total Sapling balance $saplingTotalBalance must not be " +
"less than verified Sapling balance $saplingVerifiedBalance."
require(saplingVerifiedBalance >= MIN_INCLUSIVE) {
"Sapling verified balance $saplingVerifiedBalance must by equal or above $MIN_INCLUSIVE"
}
require(orchardTotalBalance >= orchardVerifiedBalance) {
"Total Orchard balance $orchardTotalBalance must not be " +
"less than verified Orchard balance $orchardVerifiedBalance."
require(saplingChangePending >= MIN_INCLUSIVE) {
"Sapling change pending $saplingChangePending must by equal or above $MIN_INCLUSIVE"
}
require(saplingValuePending >= MIN_INCLUSIVE) {
"Sapling value pending $saplingValuePending must by equal or above $MIN_INCLUSIVE"
}
require(orchardVerifiedBalance >= MIN_INCLUSIVE) {
"Orchard verified balance $orchardVerifiedBalance must by equal or above $MIN_INCLUSIVE"
}
require(orchardChangePending >= MIN_INCLUSIVE) {
"Orchard change pending $orchardChangePending must by equal or above $MIN_INCLUSIVE"
}
require(orchardValuePending >= MIN_INCLUSIVE) {
"Orchard value pending $orchardValuePending must by equal or above $MIN_INCLUSIVE"
}
require(unshieldedBalance >= MIN_INCLUSIVE) {
"Unshielded balance $unshieldedBalance must by equal or above $MIN_INCLUSIVE"
}
}
companion object {
const val MIN_INCLUSIVE = 0
}
}

View File

@ -1148,23 +1148,31 @@ fn encode_account_balance<'a>(
account: &AccountId,
balance: &AccountBalance,
) -> jni::errors::Result<JObject<'a>> {
let sapling_total_balance = Amount::from(balance.sapling_balance().total());
let sapling_verified_balance = Amount::from(balance.sapling_balance().spendable_value());
let sapling_change_pending =
Amount::from(balance.sapling_balance().change_pending_confirmation());
let sapling_value_pending =
Amount::from(balance.sapling_balance().value_pending_spendability());
let orchard_total_balance = Amount::from(balance.orchard_balance().total());
let orchard_verified_balance = Amount::from(balance.orchard_balance().spendable_value());
let orchard_change_pending =
Amount::from(balance.orchard_balance().change_pending_confirmation());
let orchard_value_pending =
Amount::from(balance.orchard_balance().value_pending_spendability());
let unshielded = Amount::from(balance.unshielded());
env.new_object(
JNI_ACCOUNT_BALANCE,
"(IJJJJJ)V",
"(IJJJJJJJ)V",
&[
JValue::Int(u32::from(*account) as i32),
JValue::Long(sapling_total_balance.into()),
JValue::Long(sapling_verified_balance.into()),
JValue::Long(orchard_total_balance.into()),
JValue::Long(sapling_change_pending.into()),
JValue::Long(sapling_value_pending.into()),
JValue::Long(orchard_verified_balance.into()),
JValue::Long(orchard_change_pending.into()),
JValue::Long(orchard_value_pending.into()),
JValue::Long(unshielded.into()),
],
)

View File

@ -4,26 +4,32 @@ import cash.z.ecc.android.sdk.internal.model.JniAccountBalance
object JniAccountBalanceFixture {
const val ACCOUNT_ID: Int = 0
const val SAPLING_TOTAL_BALANCE: Long = 0L
const val SAPLING_VERIFIED_BALANCE: Long = 0L
const val ORCHARD_TOTAL_BALANCE: Long = 0L
const val SAPLING_CHANGE_PENDING: Long = 0L
const val SAPLING_VALUE_PENDING: Long = 0L
const val ORCHARD_VERIFIED_BALANCE: Long = 0L
const val ORCHARD_CHANGE_PENDING: Long = 0L
const val ORCHARD_VALUE_PENDING: Long = 0L
const val UNSHIELDED_BALANCE: Long = 0L
@Suppress("LongParameterList")
fun new(
account: Int = ACCOUNT_ID,
saplingTotalBalance: Long = SAPLING_TOTAL_BALANCE,
saplingVerifiedBalance: Long = SAPLING_VERIFIED_BALANCE,
orchardTotalBalance: Long = ORCHARD_TOTAL_BALANCE,
saplingChangePending: Long = SAPLING_CHANGE_PENDING,
saplingValuePending: Long = SAPLING_VALUE_PENDING,
orchardVerifiedBalance: Long = ORCHARD_VERIFIED_BALANCE,
orchardChangePending: Long = ORCHARD_CHANGE_PENDING,
orchardValuePending: Long = ORCHARD_VALUE_PENDING,
unshieldedBalance: Long = UNSHIELDED_BALANCE,
) = JniAccountBalance(
account = account,
saplingTotalBalance = saplingTotalBalance,
saplingVerifiedBalance = saplingVerifiedBalance,
orchardTotalBalance = orchardTotalBalance,
saplingChangePending = saplingChangePending,
saplingValuePending = saplingValuePending,
orchardVerifiedBalance = orchardVerifiedBalance,
unshieldedBalance = unshieldedBalance
orchardChangePending = orchardChangePending,
orchardValuePending = orchardValuePending,
unshieldedBalance = unshieldedBalance,
)
}

View File

@ -13,12 +13,12 @@ internal data class AccountBalance(
return AccountBalance(
sapling =
WalletBalance(
Zatoshi(jni.saplingTotalBalance),
Zatoshi(jni.saplingVerifiedBalance + jni.saplingChangePending + jni.saplingValuePending),
Zatoshi(jni.saplingVerifiedBalance)
),
orchard =
WalletBalance(
Zatoshi(jni.orchardTotalBalance),
Zatoshi(jni.orchardVerifiedBalance + jni.orchardChangePending + jni.orchardValuePending),
Zatoshi(jni.orchardVerifiedBalance)
),
unshielded = Zatoshi(jni.unshieldedBalance)