Update to use data access API in librustzcash. (#172)

* Refactor to updated data access API.

* Update to latest librustzcash/data_access_api.

Co-authored-by: Kevin Gorham <kevin.gorham@electriccoin.co>
This commit is contained in:
Kris Nuttycombe 2021-03-10 11:31:55 -07:00 committed by GitHub
parent 794a9f99b8
commit 4bcf74d871
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 402 additions and 340 deletions

396
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -56,6 +56,12 @@ zcash_proofs = { git = 'https://github.com/zcash/librustzcash.git', rev='04a2bd4
#zcash_primitives = { path = '../../clones/librustzcash/zcash_primitives' }
#zcash_proofs = { path = '../../clones/librustzcash/zcash_proofs' }
[patch.crates-io]
zcash_client_backend = {git = "https://github.com/nuttycom/librustzcash", branch = "data_access_api"}
zcash_client_sqlite = {git = "https://github.com/nuttycom/librustzcash", branch = "data_access_api"}
zcash_primitives = {git = "https://github.com/nuttycom/librustzcash", branch = "data_access_api"}
zcash_proofs = {git = "https://github.com/nuttycom/librustzcash", branch = "data_access_api"}
[features]
mainnet = ["zcash_client_sqlite/mainnet"]
updater = ["bls12_381", "futures", "grpc", "grpc-protobuf", "httpbis", "tls-api", "tls-api-rustls"]

View File

@ -11,64 +11,49 @@ use jni::{
sys::{jboolean, jbyteArray, jint, jlong, JNI_FALSE, JNI_TRUE, jobjectArray, jstring},
};
use log::Level;
use protobuf::{Message, parse_from_bytes};
use secp256k1::{PublicKey, Secp256k1};
use sha2::{Digest, Sha256};
use std::convert::{TryFrom, TryInto};
use std::panic;
use std::path::Path;
use std::ptr;
use zcash_client_backend::{
address::RecipientAddress,
data_api::{
chain::{scan_cached_blocks, validate_chain},
error::Error,
wallet::{create_spend_to_address, decrypt_and_store_transaction},
WalletRead, WalletWrite,
},
encoding::{
decode_extended_full_viewing_key, decode_extended_spending_key,
encode_extended_full_viewing_key, encode_extended_spending_key, encode_payment_address,
},
keys::spending_key,
wallet::{AccountId, OvkPolicy},
};
use zcash_client_sqlite::{
chain::{rewind_to_height, validate_combined_chain},
error::ErrorKind,
init::{init_accounts_table, init_blocks_table, init_data_database},
query::{
get_address, get_balance, get_received_memo_as_utf8, get_sent_memo_as_utf8,
get_verified_balance,
},
scan::{decrypt_and_store_transaction, scan_cached_blocks},
transact::{create_to_address, OvkPolicy},
wallet::init::{init_accounts_table, init_blocks_table, init_data_database},
BlockDB, NoteId, WalletDB,
};
use zcash_primitives::{
block::BlockHash,
consensus::{BlockHeight, BranchId},
consensus::{BlockHeight, BranchId, Parameters},
legacy::TransparentAddress,
note_encryption::Memo,
transaction::{components::Amount, Transaction},
zip32::ExtendedFullViewingKey,
};
#[cfg(feature = "mainnet")]
use zcash_primitives::consensus::MainNetwork as Network;
use zcash_primitives::consensus::{MainNetwork, MAIN_NETWORK};
#[cfg(not(feature = "mainnet"))]
use zcash_primitives::consensus::TestNetwork as Network;
#[cfg(feature = "mainnet")]
use zcash_primitives::constants::mainnet::{
COIN_TYPE, HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, HRP_SAPLING_EXTENDED_SPENDING_KEY,
HRP_SAPLING_PAYMENT_ADDRESS,
};
#[cfg(feature = "mainnet")]
use zcash_primitives::constants::mainnet::B58_PUBKEY_ADDRESS_PREFIX;
#[cfg(not(feature = "mainnet"))]
use zcash_primitives::constants::testnet::{
COIN_TYPE, HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, HRP_SAPLING_EXTENDED_SPENDING_KEY,
HRP_SAPLING_PAYMENT_ADDRESS,
};
#[cfg(not(feature = "mainnet"))]
use zcash_primitives::constants::testnet::B58_PUBKEY_ADDRESS_PREFIX;
use zcash_primitives::legacy::TransparentAddress;
use zcash_proofs::prover::LocalTxProver;
use zcash_primitives::consensus::{TestNetwork, TEST_NETWORK};
use local_rpc_types::{TransactionDataList, TransparentTransaction, TransparentTransactionList};
use std::convert::TryFrom;
use std::convert::TryInto;
use std::panic;
use std::path::Path;
use std::ptr;
use protobuf::{parse_from_bytes, Message};
use sha2::{Digest, Sha256};
use crate::utils::exception::unwrap_exc_or;
use hdwallet::{ExtendedPrivKey, KeyIndex};
use secp256k1::{PublicKey, Secp256k1};
mod utils;
@ -88,6 +73,22 @@ fn print_debug_state() {
debug!("Release enabled (congrats, this is NOT a debug build).");
}
#[cfg(feature = "mainnet")]
pub const NETWORK: MainNetwork = MAIN_NETWORK;
#[cfg(not(feature = "mainnet"))]
pub const NETWORK: TestNetwork = TEST_NETWORK;
fn wallet_db(env: &JNIEnv<'_>, db_data: JString<'_>) -> Result<WalletDB, failure::Error> {
WalletDB::for_path(utils::java_string_to_rust(&env, db_data))
.map_err(|e| format_err!("Error opening wallet database connection: {}", e))
}
fn block_db(env: &JNIEnv<'_>, db_data: JString<'_>) -> Result<BlockDB, failure::Error> {
BlockDB::for_path(utils::java_string_to_rust(&env, db_data))
.map_err(|e| format_err!("Error opening block source database connection: {}", e))
}
#[no_mangle]
pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_initLogs(
_env: JNIEnv<'_>,
@ -112,9 +113,9 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_initDataDb(
db_data: JString<'_>,
) -> jboolean {
let res = panic::catch_unwind(|| {
let db_data = utils::java_string_to_rust(&env, db_data);
init_data_database(&db_data)
let db_path = utils::java_string_to_rust(&env, db_data);
WalletDB::for_path(db_path)
.and_then(|db| init_data_database(&db))
.map(|()| JNI_TRUE)
.map_err(|e| format_err!("Error while initializing data DB: {}", e))
});
@ -130,7 +131,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_initAccount
accounts: jint,
) -> jobjectArray {
let res = panic::catch_unwind(|| {
let db_data = utils::java_string_to_rust(&env, db_data);
let db_data = wallet_db(&env, db_data)?;
let seed = env.convert_byte_array(seed).unwrap();
let accounts = if accounts >= 0 {
accounts as u32
@ -139,29 +140,29 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_initAccount
};
let extsks: Vec<_> = (0..accounts)
.map(|account| spending_key(&seed, COIN_TYPE, account))
.map(|account| spending_key(&seed, NETWORK.coin_type(), account))
.collect();
let extfvks: Vec<_> = extsks.iter().map(ExtendedFullViewingKey::from).collect();
match init_accounts_table(&db_data, &Network, &extfvks) {
Ok(()) => {
init_accounts_table(&db_data, &NETWORK, &extfvks)
.map(|_| {
// Return the ExtendedSpendingKeys for the created accounts
Ok(utils::rust_vec_to_java(
utils::rust_vec_to_java(
&env,
extsks,
"java/lang/String",
|env, extsk| {
env.new_string(encode_extended_spending_key(
HRP_SAPLING_EXTENDED_SPENDING_KEY,
NETWORK.hrp_sapling_extended_spending_key(),
&extsk,
))
},
|env| env.new_string(""),
))
}
Err(e) => Err(format_err!("Error while initializing accounts: {}", e)),
}
)
})
.map_err(|e| format_err!("Error while initializing accounts: {}", e))
});
unwrap_exc_or(&env, res, ptr::null_mut())
}
@ -173,20 +174,23 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_initAccount
extfvks_arr: jobjectArray,
) -> jboolean {
let res = panic::catch_unwind(|| {
let db_data = utils::java_string_to_rust(&env, db_data);
let db_data = wallet_db(&env, db_data)?;
// TODO: avoid all this unwrapping and also surface errors, better
let count = env.get_array_length(extfvks_arr).unwrap();
let extfvks = (0..count)
.map(|i| env.get_object_array_element(extfvks_arr, i))
.map(|jstr| utils::java_string_to_rust(&env, jstr.unwrap().into()))
.map(|vkstr| {
decode_extended_full_viewing_key(HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, &vkstr)
.unwrap()
.unwrap()
decode_extended_full_viewing_key(
NETWORK.hrp_sapling_extended_full_viewing_key(),
&vkstr,
)
.unwrap()
.unwrap()
})
.collect::<Vec<_>>();
match init_accounts_table(&db_data, &Network, &extfvks) {
match init_accounts_table(&db_data, &NETWORK, &extfvks) {
Ok(()) => Ok(JNI_TRUE),
Err(e) => Err(format_err!("Error while initializing accounts: {}", e)),
}
@ -210,7 +214,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_tool_DerivationTool_deriveE
};
let extsks: Vec<_> = (0..accounts)
.map(|account| spending_key(&seed, COIN_TYPE, account))
.map(|account| spending_key(&seed, NETWORK.coin_type(), account))
.collect();
Ok(utils::rust_vec_to_java(
@ -219,7 +223,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_tool_DerivationTool_deriveE
"java/lang/String",
|env, extsk| {
env.new_string(encode_extended_spending_key(
HRP_SAPLING_EXTENDED_SPENDING_KEY,
NETWORK.hrp_sapling_extended_spending_key(),
&extsk,
))
},
@ -245,7 +249,9 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_tool_DerivationTool_deriveE
};
let extfvks: Vec<_> = (0..accounts)
.map(|account| ExtendedFullViewingKey::from(&spending_key(&seed, COIN_TYPE, account)))
.map(|account| {
ExtendedFullViewingKey::from(&spending_key(&seed, NETWORK.coin_type(), account))
})
.collect();
Ok(utils::rust_vec_to_java(
@ -254,7 +260,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_tool_DerivationTool_deriveE
"java/lang/String",
|env, extfvk| {
env.new_string(encode_extended_full_viewing_key(
HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
NETWORK.hrp_sapling_extended_full_viewing_key(),
&extfvk,
))
},
@ -279,11 +285,11 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_tool_DerivationTool_deriveS
return Err(format_err!("accountIndex argument must be positive"));
};
let address = spending_key(&seed, COIN_TYPE, account_index)
let address = spending_key(&seed, NETWORK.coin_type(), account_index)
.default_address()
.unwrap()
.1;
let address_str = encode_payment_address(HRP_SAPLING_PAYMENT_ADDRESS, &address);
let address_str = encode_payment_address(NETWORK.hrp_sapling_payment_address(), &address);
let output = env
.new_string(address_str)
.expect("Couldn't create Java string!");
@ -301,7 +307,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_tool_DerivationTool_deriveS
let res = panic::catch_unwind(|| {
let extfvk_string = utils::java_string_to_rust(&env, extfvk_string);
let extfvk = match decode_extended_full_viewing_key(
HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
NETWORK.hrp_sapling_extended_full_viewing_key(),
&extfvk_string,
) {
Ok(Some(extfvk)) => extfvk,
@ -317,7 +323,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_tool_DerivationTool_deriveS
};
let address = extfvk.default_address().unwrap().1;
let address_str = encode_payment_address(HRP_SAPLING_PAYMENT_ADDRESS, &address);
let address_str = encode_payment_address(NETWORK.hrp_sapling_payment_address(), &address);
let output = env
.new_string(address_str)
.expect("Couldn't create Java string!");
@ -335,7 +341,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_tool_DerivationTool_deriveE
let res = panic::catch_unwind(|| {
let extsk_string = utils::java_string_to_rust(&env, extsk_string);
let extfvk = match decode_extended_spending_key(
HRP_SAPLING_EXTENDED_SPENDING_KEY,
NETWORK.hrp_sapling_extended_spending_key(),
&extsk_string,
) {
Ok(Some(extsk)) => ExtendedFullViewingKey::from(&extsk),
@ -352,7 +358,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_tool_DerivationTool_deriveE
let output = env
.new_string(encode_extended_full_viewing_key(
HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
NETWORK.hrp_sapling_extended_full_viewing_key(),
&extfvk,
))
.expect("Couldn't create Java string!");
@ -373,7 +379,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_initBlocksT
sapling_tree_string: JString<'_>,
) -> jboolean {
let res = panic::catch_unwind(|| {
let db_data = utils::java_string_to_rust(&env, db_data);
let db_data = wallet_db(&env, db_data)?;
let hash = {
let mut hash = hex::decode(utils::java_string_to_rust(&env, hash_string)).unwrap();
hash.reverse();
@ -388,7 +394,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_initBlocksT
hex::decode(utils::java_string_to_rust(&env, sapling_tree_string)).unwrap();
debug!("initializing blocks table with height {}", height);
match init_blocks_table(&db_data, height, hash, time, &sapling_tree) {
match init_blocks_table(&db_data, height.try_into()?, hash, time, &sapling_tree) {
Ok(()) => Ok(JNI_TRUE),
Err(e) => Err(format_err!("Error while initializing blocks table: {}", e)),
}
@ -404,21 +410,25 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_getAddress(
account: jint,
) -> jstring {
let res = panic::catch_unwind(|| {
let db_data = utils::java_string_to_rust(&env, db_data);
let account = if account >= 0 {
account as u32
} else {
return Err(format_err!("account argument must be positive"));
};
let db_data = wallet_db(&env, db_data)?;
let account = AccountId(account.try_into()?);
match get_address(&db_data, account) {
Ok(addr) => {
let output = env.new_string(addr).expect("Couldn't create Java string!");
match (&db_data).get_address(&NETWORK, account) {
Ok(Some(addr)) => {
let addr_str = encode_payment_address(NETWORK.hrp_sapling_payment_address(), &addr);
let output = env
.new_string(addr_str)
.expect("Couldn't create Java string!");
Ok(output.into_inner())
}
Ok(None) => Err(format_err!(
"No payment address was available for account {:?}",
account
)),
Err(e) => Err(format_err!("Error while fetching address: {}", e)),
}
});
unwrap_exc_or(&env, res, ptr::null_mut())
}
@ -431,7 +441,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_isValidShie
let res = panic::catch_unwind(|| {
let addr = utils::java_string_to_rust(&env, addr);
match RecipientAddress::decode(&Network, &addr) {
match RecipientAddress::decode(&NETWORK, &addr) {
Some(addr) => match addr {
RecipientAddress::Shielded(_) => Ok(JNI_TRUE),
RecipientAddress::Transparent(_) => Ok(JNI_FALSE),
@ -451,7 +461,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_isValidTran
let res = panic::catch_unwind(|| {
let addr = utils::java_string_to_rust(&env, addr);
match RecipientAddress::decode(&Network, &addr) {
match RecipientAddress::decode(&NETWORK, &addr) {
Some(addr) => match addr {
RecipientAddress::Shielded(_) => Ok(JNI_FALSE),
RecipientAddress::Transparent(_) => Ok(JNI_TRUE),
@ -470,14 +480,10 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_getBalance(
account: jint,
) -> jlong {
let res = panic::catch_unwind(|| {
let db_data = utils::java_string_to_rust(&env, db_data);
let account = if account >= 0 {
account as u32
} else {
return Err(format_err!("account argument must be positive"));
};
let db_data = wallet_db(&env, db_data)?;
let account = AccountId(account.try_into()?);
match get_balance(&db_data, account) {
match (&db_data).get_balance(account) {
Ok(balance) => Ok(balance.into()),
Err(e) => Err(format_err!("Error while fetching balance: {}", e)),
}
@ -493,18 +499,25 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_getVerified
account: jint,
) -> jlong {
let res = panic::catch_unwind(|| {
let db_data = utils::java_string_to_rust(&env, db_data);
let account = if account >= 0 {
account as u32
} else {
return Err(format_err!("account argument must be positive"));
};
let db_data = wallet_db(&env, db_data)?;
let account = AccountId(account.try_into()?);
match get_verified_balance(&db_data, account) {
Ok(balance) => Ok(balance.into()),
Err(e) => Err(format_err!("Error while fetching verified balance: {}", e)),
}
(&db_data)
.get_target_and_anchor_heights()
.map_err(|e| format_err!("Error while fetching anchor height: {}", e))
.and_then(|opt_anchor| {
opt_anchor
.map(|(_, a)| a)
.ok_or(format_err!("Anchor height not available; scan required."))
})
.and_then(|anchor| {
(&db_data)
.get_verified_balance(account, anchor)
.map_err(|e| format_err!("Error while fetching verified balance: {}", e))
})
.map(|amount| amount.into())
});
unwrap_exc_or(&env, res, -1)
}
@ -516,9 +529,9 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_getReceived
id_note: jlong,
) -> jstring {
let res = panic::catch_unwind(|| {
let db_data = utils::java_string_to_rust(&env, db_data);
let db_data = wallet_db(&env, db_data)?;
let memo = match get_received_memo_as_utf8(db_data, id_note) {
let memo = match (&db_data).get_received_memo_as_utf8(NoteId(id_note)) {
Ok(memo) => memo.unwrap_or_default(),
Err(e) => return Err(format_err!("Error while fetching memo: {}", e)),
};
@ -537,16 +550,17 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_getSentMemo
id_note: jlong,
) -> jstring {
let res = panic::catch_unwind(|| {
let db_data = utils::java_string_to_rust(&env, db_data);
let db_data = wallet_db(&env, db_data)?;
let memo = match get_sent_memo_as_utf8(db_data, id_note) {
Ok(memo) => memo.unwrap_or_default(),
Err(e) => return Err(format_err!("Error while fetching memo: {}", e)),
};
let memo = (&db_data)
.get_sent_memo_as_utf8(NoteId(id_note))
.map(|memo| memo.unwrap_or_default())
.map_err(|e| format_err!("Error while fetching memo: {}", e))?;
let output = env.new_string(memo).expect("Couldn't create Java string!");
Ok(output.into_inner())
});
unwrap_exc_or(&env, res, ptr::null_mut())
}
@ -558,13 +572,19 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_validateCom
db_data: JString<'_>,
) -> jint {
let res = panic::catch_unwind(|| {
let db_cache = utils::java_string_to_rust(&env, db_cache);
let db_data = utils::java_string_to_rust(&env, db_data);
let block_db = block_db(&env, db_cache)?;
let db_data = wallet_db(&env, db_data)?;
if let Err(e) = validate_combined_chain(Network, &db_cache, &db_data) {
match e.kind() {
ErrorKind::InvalidChain(upper_bound, _) => {
let upper_bound_u32 = u32::from(*upper_bound);
let validate_from = (&db_data)
.get_max_height_hash()
.map_err(|e| format_err!("Error while validating chain: {}", e))?;
let val_res = validate_chain(&NETWORK, &block_db, validate_from);
if let Err(e) = val_res {
match e.0 {
Error::InvalidChain(upper_bound, _) => {
let upper_bound_u32 = u32::from(upper_bound);
Ok(upper_bound_u32 as i32)
}
_ => Err(format_err!("Error while validating chain: {}", e)),
@ -574,6 +594,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_validateCom
Ok(-1)
}
});
unwrap_exc_or(&env, res, 0)
}
@ -585,17 +606,18 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_rewindToHei
height: jint,
) -> jboolean {
let res = panic::catch_unwind(|| {
let db_data = utils::java_string_to_rust(&env, db_data);
let db_data = wallet_db(&env, db_data)?;
let mut update_ops = (&db_data)
.get_update_ops()
.map_err(|e| format_err!("Could not obtain a writable database connection: {}", e))?;
match rewind_to_height(Network, &db_data, BlockHeight::from(height as u32)) {
Ok(()) => Ok(JNI_TRUE),
Err(e) => Err(format_err!(
"Error while rewinding data DB to height {}: {}",
height,
e
)),
}
let height = BlockHeight::try_from(height)?;
(&mut update_ops)
.transactionally(|ops| ops.rewind_to_height(&NETWORK, height))
.map(|_| JNI_TRUE)
.map_err(|e| format_err!("Error while rewinding data DB to height {}: {}", height, e))
});
unwrap_exc_or(&env, res, JNI_FALSE)
}
@ -607,10 +629,10 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_scanBlocks(
db_data: JString<'_>,
) -> jboolean {
let res = panic::catch_unwind(|| {
let db_cache = utils::java_string_to_rust(&env, db_cache);
let db_data = utils::java_string_to_rust(&env, db_data);
let db_cache = block_db(&env, db_cache)?;
let db_data = wallet_db(&env, db_data)?;
match scan_cached_blocks(&Network, &db_cache, &db_data, None) {
match scan_cached_blocks(&NETWORK, &db_cache, &db_data, None) {
Ok(()) => Ok(JNI_TRUE),
Err(e) => Err(format_err!("Error while scanning blocks: {}", e)),
}
@ -628,10 +650,10 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_scanBlockBa
limit: jint,
) -> jboolean {
let res = panic::catch_unwind(|| {
let db_cache = utils::java_string_to_rust(&env, db_cache);
let db_data = utils::java_string_to_rust(&env, db_data);
let db_cache = block_db(&env, db_cache)?;
let db_data = wallet_db(&env, db_data)?;
match scan_cached_blocks(&Network, &db_cache, &db_data, Some(limit.try_into().unwrap())) {
match scan_cached_blocks(&NETWORK, &db_cache, &db_data, Some(limit as u32)) {
Ok(()) => Ok(JNI_TRUE),
Err(e) => Err(format_err!("Error while scanning blocks: {}", e)),
}
@ -658,7 +680,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_parseTransa
for data in input_tx_data.data.iter() {
let mut tx = TransparentTransaction::new();
let parsed = Transaction::read(&data[..])?;
tx.set_expiryHeight(u32::from(parsed.expiry_height));
tx.set_expiryHeight(parsed.expiry_height.into());
// Note: the wrong value is returned here (negative numbers)
tx.set_value(i64::from(parsed.value_balance));
tx.set_hasShieldedSpends(parsed.shielded_spends.len() > 0);
@ -668,7 +690,9 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_parseTransa
match vout.script_pubkey.address() {
// NOTE : this logic below doesn't work. No address is parsed.
Some(TransparentAddress::PublicKey(hash)) => {
tx.set_toAddress(hash.to_base58check(&B58_PUBKEY_ADDRESS_PREFIX, &[]));
tx.set_toAddress(
hash.to_base58check(&NETWORK.b58_pubkey_address_prefix(), &[]),
);
}
_ => {}
}
@ -701,7 +725,9 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_tool_DerivationTool_deriveT
let address_sk = ext_t_key
.derive_private_key(KeyIndex::hardened_from_normalize_index(44).unwrap())
.unwrap()
.derive_private_key(KeyIndex::hardened_from_normalize_index(COIN_TYPE).unwrap())
.derive_private_key(
KeyIndex::hardened_from_normalize_index(NETWORK.coin_type()).unwrap(),
)
.unwrap()
.derive_private_key(KeyIndex::hardened_from_normalize_index(0).unwrap())
.unwrap()
@ -716,7 +742,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_tool_DerivationTool_deriveT
hash160.update(Sha256::digest(&pk.serialize()[..].to_vec()));
let address_string = hash160
.finalize()
.to_base58check(&B58_PUBKEY_ADDRESS_PREFIX, &[]);
.to_base58check(&NETWORK.b58_pubkey_address_prefix(), &[]);
let output = env
.new_string(address_string)
@ -734,15 +760,16 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_decryptAndS
tx: jbyteArray,
) -> jboolean {
let res = panic::catch_unwind(|| {
let db_data = utils::java_string_to_rust(&env, db_data);
let db_data = wallet_db(&env, db_data)?;
let tx_bytes = env.convert_byte_array(tx).unwrap();
let tx = Transaction::read(&tx_bytes[..])?;
match decrypt_and_store_transaction(&db_data, &Network, &tx) {
match decrypt_and_store_transaction(&NETWORK, &db_data, &tx) {
Ok(()) => Ok(JNI_TRUE),
Err(e) => Err(format_err!("Error while decrypting transaction: {}", e)),
}
});
unwrap_exc_or(&env, res, JNI_FALSE)
}
@ -751,7 +778,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_createToAdd
env: JNIEnv<'_>,
_: JClass<'_>,
db_data: JString<'_>,
consensus_branch_id: jlong,
_: jlong, // was: consensus_branch_id; this is now derived from target/anchor height
account: jint,
extsk: JString<'_>,
to: JString<'_>,
@ -761,7 +788,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_createToAdd
output_params: JString<'_>,
) -> jlong {
let res = panic::catch_unwind(|| {
let db_data = utils::java_string_to_rust(&env, db_data);
let db_data = wallet_db(&env, db_data)?;
let account = if account >= 0 {
account as u32
} else {
@ -778,17 +805,19 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_createToAdd
let spend_params = utils::java_string_to_rust(&env, spend_params);
let output_params = utils::java_string_to_rust(&env, output_params);
let extsk = match decode_extended_spending_key(HRP_SAPLING_EXTENDED_SPENDING_KEY, &extsk) {
Ok(Some(extsk)) => extsk,
Ok(None) => {
return Err(format_err!("ExtendedSpendingKey is for the wrong network"));
}
Err(e) => {
return Err(format_err!("Invalid ExtendedSpendingKey: {}", e));
}
};
let extsk =
match decode_extended_spending_key(NETWORK.hrp_sapling_extended_spending_key(), &extsk)
{
Ok(Some(extsk)) => extsk,
Ok(None) => {
return Err(format_err!("ExtendedSpendingKey is for the wrong network"));
}
Err(e) => {
return Err(format_err!("Invalid ExtendedSpendingKey: {}", e));
}
};
let to = match RecipientAddress::decode(&Network, &to) {
let to = match RecipientAddress::decode(&NETWORK, &to) {
Some(to) => to,
None => {
return Err(format_err!("Address is for the wrong network"));
@ -799,20 +828,13 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_createToAdd
let prover = LocalTxProver::new(Path::new(&spend_params), Path::new(&output_params));
let branch_id = match BranchId::try_from(consensus_branch_id as u32) {
Ok(branch) => branch,
Err(e) => {
return Err(format_err!("Invalid consensus branch id: {}", e));
}
};
// let branch = if
create_to_address(
create_spend_to_address(
&db_data,
&Network,
branch_id,
&NETWORK,
prover,
(account, &extsk),
AccountId(account),
&extsk,
&to,
value,
memo,
@ -830,7 +852,7 @@ pub unsafe extern "C" fn Java_cash_z_ecc_android_sdk_jni_RustBackend_branchIdFor
height: jint,
) -> jint {
let res = panic::catch_unwind(|| {
let branch: BranchId = BranchId::for_height::<Network>(&Network, BlockHeight::from(height as u32));
let branch: BranchId = BranchId::for_height(&NETWORK, BlockHeight::from(height as u32));
let branch_id: u32 = u32::from(branch);
debug!("For height {} found consensus branch {:?}", height, branch);
Ok(branch_id as i32)

View File

@ -1,4 +1,4 @@
// This file is generated by rust-protobuf 2.17.0. Do not edit
// This file is generated by rust-protobuf 2.18.1. Do not edit
// @generated
// https://github.com/rust-lang/rust-clippy/issues/702
@ -21,7 +21,7 @@
/// Generated files are compatible only with the same version
/// of protobuf runtime.
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_17_0;
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_18_1;
#[derive(PartialEq,Clone,Default)]
pub struct TransactionDataList {

View File

@ -44,10 +44,10 @@ pub fn unwrap_exc_or<T>(env: &JNIEnv, res: ExceptionResult<T>, error_val: T) ->
}
}
// Same as `unwrap_exc_or` but returns default value.
pub fn unwrap_exc_or_default<T: Default>(env: &JNIEnv, res: ExceptionResult<T>) -> T {
unwrap_exc_or(env, res, T::default())
}
// // Same as `unwrap_exc_or` but returns default value.
// pub fn unwrap_exc_or_default<T: Default>(env: &JNIEnv, res: ExceptionResult<T>) -> T {
// unwrap_exc_or(env, res, T::default())
// }
// Calls a corresponding `JNIEnv` method, so exception will be thrown when execution returns to
// the Java side.