Migrate to `zcash_client_sqlite 0.9.0`
The backend now supports proposals that create multiple transactions. It still does not generate such proposals itself, and we assert this inside the now-deprecated APIs.
This commit is contained in:
parent
abffb3f9ee
commit
99e91fa8b7
|
@ -469,7 +469,8 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
|||
[[package]]
|
||||
name = "equihash"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/zcash/librustzcash.git?rev=9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a#9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab579d7cf78477773b03e80bc2f89702ef02d7112c711d54ca93dcdce68533d5"
|
||||
dependencies = [
|
||||
"blake2b_simd",
|
||||
"byteorder",
|
||||
|
@ -494,7 +495,8 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "f4jumble"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zcash/librustzcash.git?rev=9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a#9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a83e8d7fd0c526af4aad893b7c9fe41e2699ed8a776a6c74aecdeafe05afc75"
|
||||
dependencies = [
|
||||
"blake2b_simd",
|
||||
]
|
||||
|
@ -1035,9 +1037,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
|||
|
||||
[[package]]
|
||||
name = "orchard"
|
||||
version = "0.7.0"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92c801aeaccd19bb6916d71f25694b62d223061872900e8022221c1ad8dcad2d"
|
||||
checksum = "1fb255c3ffdccd3c84fe9ebed72aef64fdc72e6a3e4180dd411002d47abaad42"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"bitvec",
|
||||
|
@ -1455,9 +1457,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sapling-crypto"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f5de898a7cdb7f6d9c8fb888341b6ae6e2aeae88227b7f435f1dda49ecf9e62"
|
||||
checksum = "d183012062dfdde85f7e3e758328fcf6e9846d8dd3fce35b04d0efcb6677b0e0"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"bellman",
|
||||
|
@ -2169,7 +2171,6 @@ dependencies = [
|
|||
"jni",
|
||||
"libc",
|
||||
"log-panics",
|
||||
"orchard",
|
||||
"paranoid-android",
|
||||
"prost",
|
||||
"rayon",
|
||||
|
@ -2190,7 +2191,8 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "zcash_address"
|
||||
version = "0.3.1"
|
||||
source = "git+https://github.com/zcash/librustzcash.git?rev=9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a#9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bce173f1d9ed4f806e310bc3a873301531e7a6dc209928584d6404e3f8228ef4"
|
||||
dependencies = [
|
||||
"bech32",
|
||||
"bs58",
|
||||
|
@ -2200,8 +2202,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zcash_client_backend"
|
||||
version = "0.10.0"
|
||||
source = "git+https://github.com/zcash/librustzcash.git?rev=9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a#9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "185913267d824529b9547c933674963fca2b5bd84ad377a59d0f8ab6159ce798"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bech32",
|
||||
|
@ -2239,8 +2242,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zcash_client_sqlite"
|
||||
version = "0.8.1"
|
||||
source = "git+https://github.com/zcash/librustzcash.git?rev=9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a#9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e883405989b8d7275a0e1180000b7568bb3fa33e36b4806c174eb802678e2dbf"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"byteorder",
|
||||
|
@ -2250,7 +2254,6 @@ dependencies = [
|
|||
"incrementalmerkletree",
|
||||
"jubjub",
|
||||
"maybe-rayon",
|
||||
"orchard",
|
||||
"prost",
|
||||
"rusqlite",
|
||||
"sapling-crypto",
|
||||
|
@ -2271,7 +2274,8 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "zcash_encoding"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/zcash/librustzcash.git?rev=9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a#9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f03391b81727875efa6ac0661a20883022b6fba92365dc121c48fa9b00c5aac0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"nonempty",
|
||||
|
@ -2279,8 +2283,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zcash_keys"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/zcash/librustzcash.git?rev=9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a#9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48390513c05a4090533e2a1aca486f0fb6b684493b8aefedda6ee01742b3f8f6"
|
||||
dependencies = [
|
||||
"bech32",
|
||||
"bls12_381",
|
||||
|
@ -2317,8 +2322,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zcash_primitives"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/zcash/librustzcash.git?rev=9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a#9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9070e084570bb78aed4f8d71fd6254492e62c87a5d01e084183980e98117092d"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"bip0039",
|
||||
|
@ -2354,8 +2360,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zcash_proofs"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/zcash/librustzcash.git?rev=9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a#9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8a02eb1f151d9b9a6e16408d2c55ff440bd2fb232b7377277146d0fa2df9bc8"
|
||||
dependencies = [
|
||||
"bellman",
|
||||
"blake2b_simd",
|
||||
|
|
|
@ -23,11 +23,10 @@ schemer = "0.2"
|
|||
secp256k1 = "0.26"
|
||||
secrecy = "0.8"
|
||||
zcash_address = "0.3"
|
||||
zcash_client_backend = { version = "0.10", features = ["transparent-inputs", "unstable"] }
|
||||
zcash_client_sqlite = { version = "^0.8.1", features = ["transparent-inputs", "unstable"] }
|
||||
zcash_primitives = "0.13"
|
||||
zcash_proofs = "0.13"
|
||||
orchard = { version = "0.7", default-features = false }
|
||||
zcash_client_backend = { version = "0.11", features = ["transparent-inputs", "unstable"] }
|
||||
zcash_client_sqlite = { version = "0.9", features = ["transparent-inputs", "unstable"] }
|
||||
zcash_primitives = "0.14"
|
||||
zcash_proofs = "0.14"
|
||||
|
||||
# Initialization
|
||||
rayon = "1.7"
|
||||
|
@ -62,11 +61,3 @@ libc = "0.2"
|
|||
name = "zcashwalletsdk"
|
||||
path = "src/main/rust/lib.rs"
|
||||
crate-type = ["staticlib", "cdylib"]
|
||||
|
||||
[patch.crates-io]
|
||||
# Tag `ecc_sdk-20240130a`
|
||||
zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a" }
|
||||
zcash_client_backend = { git = "https://github.com/zcash/librustzcash.git", rev = "9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a" }
|
||||
zcash_client_sqlite = { git = "https://github.com/zcash/librustzcash.git", rev = "9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a" }
|
||||
zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a" }
|
||||
zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "9b5abe1a386f2c2c625d8f3fb3b6e9ce9aff641a" }
|
||||
|
|
|
@ -35,10 +35,10 @@ interface Backend {
|
|||
transparentReceiver: String? = null
|
||||
): ProposalUnsafe?
|
||||
|
||||
suspend fun createProposedTransaction(
|
||||
suspend fun createProposedTransactions(
|
||||
proposal: ProposalUnsafe,
|
||||
unifiedSpendingKey: ByteArray
|
||||
): ByteArray
|
||||
): List<ByteArray>
|
||||
|
||||
suspend fun decryptAndStoreTransaction(tx: ByteArray)
|
||||
|
||||
|
|
|
@ -328,19 +328,19 @@ class RustBackend private constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun createProposedTransaction(
|
||||
override suspend fun createProposedTransactions(
|
||||
proposal: ProposalUnsafe,
|
||||
unifiedSpendingKey: ByteArray
|
||||
): ByteArray =
|
||||
): List<ByteArray> =
|
||||
withContext(SdkDispatchers.DATABASE_IO) {
|
||||
createProposedTransaction(
|
||||
createProposedTransactions(
|
||||
dataDbFile.absolutePath,
|
||||
proposal.toByteArray(),
|
||||
unifiedSpendingKey,
|
||||
spendParamsPath = saplingSpendFile.absolutePath,
|
||||
outputParamsPath = saplingOutputFile.absolutePath,
|
||||
networkId = networkId
|
||||
)
|
||||
).asList()
|
||||
}
|
||||
|
||||
override suspend fun putUtxo(
|
||||
|
@ -599,14 +599,14 @@ class RustBackend private constructor(
|
|||
|
||||
@JvmStatic
|
||||
@Suppress("LongParameterList")
|
||||
private external fun createProposedTransaction(
|
||||
private external fun createProposedTransactions(
|
||||
dbDataPath: String,
|
||||
proposal: ByteArray,
|
||||
usk: ByteArray,
|
||||
spendParamsPath: String,
|
||||
outputParamsPath: String,
|
||||
networkId: Int
|
||||
): ByteArray
|
||||
): Array<ByteArray>
|
||||
|
||||
@JvmStatic
|
||||
private external fun branchIdForHeight(
|
||||
|
|
|
@ -38,9 +38,9 @@ class ProposalUnsafe(
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the fee required by this proposal.
|
||||
* Returns the total fee required by this proposal for its transactions.
|
||||
*/
|
||||
fun feeRequired(): Long {
|
||||
return inner.balance.feeRequired
|
||||
fun totalFeeRequired(): Long {
|
||||
return inner.stepsList.fold(0) { acc, step -> acc + step.balance.feeRequired }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,29 @@ syntax = "proto3";
|
|||
package cash.z.wallet.sdk.ffi;
|
||||
option java_package = "cash.z.wallet.sdk.internal.ffi";
|
||||
|
||||
// A data structure that describes a series of transactions to be created.
|
||||
message Proposal {
|
||||
// The version of this serialization format.
|
||||
uint32 protoVersion = 1;
|
||||
// The fee rule used in constructing this proposal
|
||||
FeeRule feeRule = 2;
|
||||
// The target height for which the proposal was constructed
|
||||
//
|
||||
// The chain must contain at least this many blocks in order for the proposal to
|
||||
// be executed.
|
||||
uint32 minTargetHeight = 3;
|
||||
// The series of transactions to be created.
|
||||
repeated ProposalStep steps = 4;
|
||||
}
|
||||
|
||||
// A data structure that describes the inputs to be consumed and outputs to
|
||||
// be produced in a proposed transaction.
|
||||
message Proposal {
|
||||
uint32 protoVersion = 1;
|
||||
message ProposalStep {
|
||||
// ZIP 321 serialized transaction request
|
||||
string transactionRequest = 2;
|
||||
string transactionRequest = 1;
|
||||
// The vector of selected payment index / output pool mappings. Payment index
|
||||
// 0 corresponds to the payment with no explicit index.
|
||||
repeated PaymentOutputPool paymentOutputPools = 2;
|
||||
// The anchor height to be used in creating the transaction, if any.
|
||||
// Setting the anchor height to zero will disallow the use of any shielded
|
||||
// inputs.
|
||||
|
@ -21,16 +38,9 @@ message Proposal {
|
|||
// The total value, fee value, and change outputs of the proposed
|
||||
// transaction
|
||||
TransactionBalance balance = 5;
|
||||
// The fee rule used in constructing this proposal
|
||||
FeeRule feeRule = 6;
|
||||
// The target height for which the proposal was constructed
|
||||
//
|
||||
// The chain must contain at least this many blocks in order for the proposal to
|
||||
// be executed.
|
||||
uint32 minTargetHeight = 7;
|
||||
// A flag indicating whether the proposal is for a shielding transaction,
|
||||
// A flag indicating whether the step is for a shielding transaction,
|
||||
// used for determining which OVK to select for wallet-internal outputs.
|
||||
bool isShielding = 8;
|
||||
bool isShielding = 6;
|
||||
}
|
||||
|
||||
enum ValuePool {
|
||||
|
@ -47,14 +57,45 @@ enum ValuePool {
|
|||
Orchard = 3;
|
||||
}
|
||||
|
||||
// The unique identifier and value for each proposed input.
|
||||
message ProposedInput {
|
||||
// A mapping from ZIP 321 payment index to the output pool that has been chosen
|
||||
// for that payment, based upon the payment address and the selected inputs to
|
||||
// the transaction.
|
||||
message PaymentOutputPool {
|
||||
uint32 paymentIndex = 1;
|
||||
ValuePool valuePool = 2;
|
||||
}
|
||||
|
||||
// The unique identifier and value for each proposed input that does not
|
||||
// require a back-reference to a prior step of the proposal.
|
||||
message ReceivedOutput {
|
||||
bytes txid = 1;
|
||||
ValuePool valuePool = 2;
|
||||
uint32 index = 3;
|
||||
uint64 value = 4;
|
||||
}
|
||||
|
||||
// A reference a payment in a prior step of the proposal. This payment must
|
||||
// belong to the wallet.
|
||||
message PriorStepOutput {
|
||||
uint32 stepIndex = 1;
|
||||
uint32 paymentIndex = 2;
|
||||
}
|
||||
|
||||
// A reference a change output from a prior step of the proposal.
|
||||
message PriorStepChange {
|
||||
uint32 stepIndex = 1;
|
||||
uint32 changeIndex = 2;
|
||||
}
|
||||
|
||||
// The unique identifier and value for an input to be used in the transaction.
|
||||
message ProposedInput {
|
||||
oneof value {
|
||||
ReceivedOutput receivedOutput = 1;
|
||||
PriorStepOutput priorStepOutput = 2;
|
||||
PriorStepChange priorStepChange = 3;
|
||||
}
|
||||
}
|
||||
|
||||
// The fee rule used in constructing a Proposal
|
||||
enum FeeRule {
|
||||
// Protobuf requires that enums have a zero discriminant as the default
|
||||
|
@ -72,15 +113,21 @@ enum FeeRule {
|
|||
|
||||
// The proposed change outputs and fee value.
|
||||
message TransactionBalance {
|
||||
// A list of change output values.
|
||||
repeated ChangeValue proposedChange = 1;
|
||||
// The fee to be paid by the proposed transaction, in zatoshis.
|
||||
uint64 feeRequired = 2;
|
||||
}
|
||||
|
||||
// A proposed change output. If the transparent value pool is selected,
|
||||
// the `memo` field must be null.
|
||||
message ChangeValue {
|
||||
// The value of a change output to be created, in zatoshis.
|
||||
uint64 value = 1;
|
||||
// The value pool in which the change output should be created.
|
||||
ValuePool valuePool = 2;
|
||||
// The optional memo that should be associated with the newly created change output.
|
||||
// Memos must not be present for transparent change outputs.
|
||||
MemoBytes memo = 3;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ use zcash_client_backend::{
|
|||
chain::{scan_cached_blocks, CommitmentTreeRoot, ScanSummary},
|
||||
scanning::{ScanPriority, ScanRange},
|
||||
wallet::{
|
||||
create_proposed_transaction, decrypt_and_store_transaction,
|
||||
create_proposed_transactions, decrypt_and_store_transaction,
|
||||
input_selection::GreedyInputSelector, propose_shielding, propose_transfer,
|
||||
},
|
||||
AccountBalance, AccountBirthday, InputSource, WalletCommitmentTrees, WalletRead,
|
||||
|
@ -524,10 +524,10 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_getTransp
|
|||
|
||||
if let Some(taddr) = ua.0.transparent() {
|
||||
let taddr = match taddr {
|
||||
TransparentAddress::PublicKey(data) => {
|
||||
TransparentAddress::PublicKeyHash(data) => {
|
||||
ZcashAddress::from_transparent_p2pkh(network, *data)
|
||||
}
|
||||
TransparentAddress::Script(data) => {
|
||||
TransparentAddress::ScriptHash(data) => {
|
||||
ZcashAddress::from_transparent_p2sh(network, *data)
|
||||
}
|
||||
};
|
||||
|
@ -1145,7 +1145,7 @@ fn encode_account_balance<'a>(
|
|||
/// pending.
|
||||
fn encode_wallet_summary<'a>(
|
||||
env: &mut JNIEnv<'a>,
|
||||
summary: WalletSummary,
|
||||
summary: WalletSummary<AccountId>,
|
||||
) -> jni::errors::Result<JObject<'a>> {
|
||||
let account_balances = utils::rust_vec_to_java(
|
||||
env,
|
||||
|
@ -1397,7 +1397,7 @@ fn zip317_helper<DbT>(
|
|||
StandardFeeRule::PreZip313
|
||||
};
|
||||
GreedyInputSelector::new(
|
||||
SingleOutputChangeStrategy::new(fee_rule, change_memo),
|
||||
SingleOutputChangeStrategy::new(fee_rule, change_memo, ShieldedProtocol::Sapling),
|
||||
DustOutputPolicy::default(),
|
||||
)
|
||||
}
|
||||
|
@ -1463,13 +1463,13 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_proposeTr
|
|||
)
|
||||
.map_err(|e| format_err!("Error creating transaction proposal: {}", e))?;
|
||||
|
||||
utils::rust_bytes_to_java(
|
||||
Ok(utils::rust_bytes_to_java(
|
||||
&env,
|
||||
Proposal::from_standard_proposal(&network, &proposal)
|
||||
.encode_to_vec()
|
||||
.as_ref(),
|
||||
)
|
||||
.map(|arr| arr.into_raw())
|
||||
)?
|
||||
.into_raw())
|
||||
});
|
||||
unwrap_exc_or(&mut env, res, ptr::null_mut())
|
||||
}
|
||||
|
@ -1574,19 +1574,19 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_proposeSh
|
|||
)
|
||||
.map_err(|e| format_err!("Error while shielding transaction: {}", e))?;
|
||||
|
||||
utils::rust_bytes_to_java(
|
||||
Ok(utils::rust_bytes_to_java(
|
||||
&env,
|
||||
Proposal::from_standard_proposal(&network, &proposal)
|
||||
.encode_to_vec()
|
||||
.as_ref(),
|
||||
)
|
||||
.map(|arr| arr.into_raw())
|
||||
)?
|
||||
.into_raw())
|
||||
});
|
||||
unwrap_exc_or(&mut env, res, ptr::null_mut())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_createProposedTransaction<
|
||||
pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_createProposedTransactions<
|
||||
'local,
|
||||
>(
|
||||
mut env: JNIEnv<'local>,
|
||||
|
@ -1597,7 +1597,7 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_createPro
|
|||
spend_params: JString<'local>,
|
||||
output_params: JString<'local>,
|
||||
network_id: jint,
|
||||
) -> jbyteArray {
|
||||
) -> jobjectArray {
|
||||
let res = catch_unwind(&mut env, |env| {
|
||||
let _span = tracing::info_span!("RustBackend.createProposedTransaction").entered();
|
||||
let network = parse_network(network_id as u32)?;
|
||||
|
@ -1612,7 +1612,7 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_createPro
|
|||
.map_err(|e| format_err!("Invalid proposal: {}", e))?
|
||||
.try_into_standard_proposal(&network, &db_data)?;
|
||||
|
||||
let txid = create_proposed_transaction::<_, _, Infallible, _, _>(
|
||||
let txids = create_proposed_transactions::<_, _, Infallible, _, _>(
|
||||
&mut db_data,
|
||||
&network,
|
||||
&prover,
|
||||
|
@ -1621,9 +1621,16 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_createPro
|
|||
OvkPolicy::Sender,
|
||||
&proposal,
|
||||
)
|
||||
.map_err(|e| format_err!("Error while creating transaction: {}", e))?;
|
||||
.map_err(|e| format_err!("Error while creating transactions: {}", e))?;
|
||||
|
||||
utils::rust_bytes_to_java(&env, txid.as_ref()).map(|arr| arr.into_raw())
|
||||
Ok(utils::rust_vec_to_java(
|
||||
env,
|
||||
txids.into(),
|
||||
"[B",
|
||||
|env, txid| utils::rust_bytes_to_java(env, txid.as_ref()),
|
||||
|env| env.new_byte_array(32),
|
||||
)?
|
||||
.into_raw())
|
||||
});
|
||||
unwrap_exc_or(&mut env, res, ptr::null_mut())
|
||||
}
|
||||
|
@ -1699,10 +1706,10 @@ pub extern "C" fn Java_cash_z_ecc_android_sdk_internal_jni_RustBackend_listTrans
|
|||
.iter()
|
||||
.map(|(taddr, _)| {
|
||||
let taddr = match taddr {
|
||||
TransparentAddress::PublicKey(data) => {
|
||||
TransparentAddress::PublicKeyHash(data) => {
|
||||
ZcashAddress::from_transparent_p2pkh(zcash_network, *data)
|
||||
}
|
||||
TransparentAddress::Script(data) => {
|
||||
TransparentAddress::ScriptHash(data) => {
|
||||
ZcashAddress::from_transparent_p2sh(zcash_network, *data)
|
||||
}
|
||||
};
|
||||
|
|
|
@ -42,10 +42,7 @@ pub(crate) fn java_nullable_string_to_rust(env: &mut JNIEnv, jstring: &JString)
|
|||
(!jstring.is_null()).then(|| java_string_to_rust(env, jstring))
|
||||
}
|
||||
|
||||
pub(crate) fn rust_bytes_to_java<'a>(
|
||||
env: &JNIEnv<'a>,
|
||||
data: &[u8],
|
||||
) -> Result<JByteArray<'a>, failure::Error> {
|
||||
pub(crate) fn rust_bytes_to_java<'a>(env: &JNIEnv<'a>, data: &[u8]) -> JNIResult<JByteArray<'a>> {
|
||||
// SAFETY: jbyte (i8) has the same size and alignment as u8, and a well-defined
|
||||
// twos-complement representation with no "trap representations".
|
||||
let buf = unsafe { slice::from_raw_parts(data.as_ptr().cast(), data.len()) };
|
||||
|
|
|
@ -95,10 +95,10 @@ internal class FakeRustBackend(
|
|||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun createProposedTransaction(
|
||||
override suspend fun createProposedTransactions(
|
||||
proposal: ProposalUnsafe,
|
||||
unifiedSpendingKey: ByteArray
|
||||
): ByteArray {
|
||||
): List<ByteArray> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
|
|
|
@ -39,10 +39,10 @@ internal interface TypesafeBackend {
|
|||
transparentReceiver: String? = null
|
||||
): Proposal?
|
||||
|
||||
suspend fun createProposedTransaction(
|
||||
suspend fun createProposedTransactions(
|
||||
proposal: Proposal,
|
||||
usk: UnifiedSpendingKey
|
||||
): FirstClassByteArray
|
||||
): List<FirstClassByteArray>
|
||||
|
||||
suspend fun getCurrentAddress(account: Account): String
|
||||
|
||||
|
|
|
@ -68,16 +68,14 @@ internal class TypesafeBackendImpl(private val backend: Backend) : TypesafeBacke
|
|||
)
|
||||
}
|
||||
|
||||
override suspend fun createProposedTransaction(
|
||||
override suspend fun createProposedTransactions(
|
||||
proposal: Proposal,
|
||||
usk: UnifiedSpendingKey
|
||||
): FirstClassByteArray =
|
||||
FirstClassByteArray(
|
||||
backend.createProposedTransaction(
|
||||
proposal.toUnsafe(),
|
||||
usk.copyBytes()
|
||||
)
|
||||
)
|
||||
): List<FirstClassByteArray> =
|
||||
backend.createProposedTransactions(
|
||||
proposal.toUnsafe(),
|
||||
usk.copyBytes()
|
||||
).map { FirstClassByteArray(it) }
|
||||
|
||||
override suspend fun getCurrentAddress(account: Account): String {
|
||||
return backend.getCurrentAddress(account.value)
|
||||
|
|
|
@ -124,11 +124,11 @@ internal class TransactionEncoderImpl(
|
|||
}
|
||||
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
val transactionId =
|
||||
val transactionIds =
|
||||
try {
|
||||
saplingParamTool.ensureParams(saplingParamTool.properties.paramsDirectory)
|
||||
Twig.debug { "params exist! attempting to send..." }
|
||||
backend.createProposedTransaction(proposal, usk)
|
||||
backend.createProposedTransactions(proposal, usk)
|
||||
} catch (t: Throwable) {
|
||||
Twig.debug(t) { "Caught exception while creating transaction." }
|
||||
throw t
|
||||
|
@ -136,11 +136,13 @@ internal class TransactionEncoderImpl(
|
|||
Twig.debug { "result of createProposedTransactions: $result" }
|
||||
}
|
||||
|
||||
val tx =
|
||||
repository.findEncodedTransactionByTxId(transactionId)
|
||||
?: throw TransactionEncoderException.TransactionNotFoundException(transactionId)
|
||||
val txs =
|
||||
transactionIds.map { transactionId ->
|
||||
repository.findEncodedTransactionByTxId(transactionId)
|
||||
?: throw TransactionEncoderException.TransactionNotFoundException(transactionId)
|
||||
}
|
||||
|
||||
return listOf(tx)
|
||||
return txs
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -223,7 +225,9 @@ internal class TransactionEncoderImpl(
|
|||
amount.value,
|
||||
memo
|
||||
)
|
||||
backend.createProposedTransaction(proposal, usk)
|
||||
val transactionIds = backend.createProposedTransactions(proposal, usk)
|
||||
assert(transactionIds.size == 1)
|
||||
transactionIds[0]
|
||||
} catch (t: Throwable) {
|
||||
Twig.debug(t) { "Caught exception while creating transaction." }
|
||||
throw t
|
||||
|
@ -244,7 +248,9 @@ internal class TransactionEncoderImpl(
|
|||
val proposal =
|
||||
backend.proposeShielding(usk.account, 100000, memo)
|
||||
?: throw SdkException("Insufficient balance (have 0, need 100000 including fee)", null)
|
||||
backend.createProposedTransaction(proposal, usk)
|
||||
val transactionIds = backend.createProposedTransactions(proposal, usk)
|
||||
assert(transactionIds.size == 1)
|
||||
transactionIds[0]
|
||||
} catch (t: Throwable) {
|
||||
// TODO [#680]: if this error matches: Insufficient balance (have 0, need 1000 including fee)
|
||||
// then consider custom error that says no UTXOs existed to shield
|
||||
|
|
|
@ -20,7 +20,7 @@ class Proposal(
|
|||
|
||||
// Check for type errors eagerly, to ensure that the caller won't
|
||||
// encounter these errors later.
|
||||
typed.feeRequired()
|
||||
typed.totalFeeRequired()
|
||||
|
||||
return typed
|
||||
}
|
||||
|
@ -34,9 +34,9 @@ class Proposal(
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the fee required by this proposal.
|
||||
* Returns the total fee required by this proposal for its transactions.
|
||||
*/
|
||||
fun feeRequired(): Zatoshi {
|
||||
return Zatoshi(inner.feeRequired())
|
||||
fun totalFeeRequired(): Zatoshi {
|
||||
return Zatoshi(inner.totalFeeRequired())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue