API: get_available_addrs

This commit is contained in:
Hanh 2023-03-14 22:07:37 +10:00
parent dbaa1c02c9
commit 8a2f2b7fea
6 changed files with 116 additions and 43 deletions

View File

@ -226,6 +226,8 @@ struct CResult_u8 convert_to_watchonly(uint8_t coin, uint32_t id_account);
struct CResult______u8 get_backup(uint8_t coin, uint32_t id_account);
struct CResult_u8 get_available_addrs(uint8_t coin, uint32_t account);
struct CResult_____c_char get_address(uint8_t coin, uint32_t id_account, uint8_t ua_type);
void import_transparent_key(uint8_t coin, uint32_t id_account, char *path);

View File

@ -3,9 +3,7 @@
// Account creation
use crate::coinconfig::CoinConfig;
use crate::db::data_generated::fb::{
BackupT, KeyPackT, AddressBalanceVecT, AddressBalanceT,
};
use crate::db::data_generated::fb::{AddressBalanceT, AddressBalanceVecT, BackupT, KeyPackT};
use crate::db::AccountData;
use crate::key2::decode_key;
use crate::orchard::OrchardKeyBytes;
@ -265,22 +263,39 @@ pub async fn get_taddr_balance(coin: u8, id_account: u32) -> anyhow::Result<u64>
/// is exceeded and no balance was found
/// # Arguments
/// * `gap_limit`: number of accounts with 0 balance before the scan stops
pub async fn scan_transparent_accounts(coin: u8, account: u32, gap_limit: usize) -> anyhow::Result<AddressBalanceVecT> {
pub async fn scan_transparent_accounts(
coin: u8,
account: u32,
gap_limit: usize,
) -> anyhow::Result<AddressBalanceVecT> {
let c = CoinConfig::get(coin);
let db = c.db()?;
let account_data = db.get_account_info(account)?;
let AccountData {
seed, aindex, ..
} = account_data;
let AccountData { seed, aindex, .. } = account_data;
let mut addresses = vec![];
if let Some(seed) = seed {
let mut client = c.connect_lwd().await?;
addresses.extend(crate::taddr::scan_transparent_accounts(c.chain.network(), &mut client, &seed, aindex, gap_limit).await?);
addresses.extend(
crate::taddr::scan_transparent_accounts(
c.chain.network(),
&mut client,
&seed,
aindex,
gap_limit,
)
.await?,
);
}
let addresses: Vec<_> = addresses.iter().map(|a| AddressBalanceT { index: a.index,
address: Some(a.address.clone()), balance: a.balance }).collect();
let addresses: Vec<_> = addresses
.iter()
.map(|a| AddressBalanceT {
index: a.index,
address: Some(a.address.clone()),
balance: a.balance,
})
.collect();
let addresses = AddressBalanceVecT {
values: Some(addresses)
values: Some(addresses),
};
Ok(addresses)
}

View File

@ -20,6 +20,13 @@ static mut POST_COBJ: Option<ffi::DartPostCObjectFnType> = None;
const MAX_COINS: u8 = 2;
fn with_coin<T, F: Fn(&Connection) -> anyhow::Result<T>>(coin: u8, f: F) -> anyhow::Result<T> {
let c = CoinConfig::get(coin);
let db = c.db()?;
let connection = &db.connection;
f(connection)
}
#[no_mangle]
pub unsafe extern "C" fn dummy_export() {}
@ -255,6 +262,15 @@ pub unsafe extern "C" fn get_backup(coin: u8, id_account: u32) -> CResult<*const
to_cresult_bytes(res())
}
#[no_mangle]
pub unsafe extern "C" fn get_available_addrs(coin: u8, account: u32) -> CResult<u8> {
let res = |connection: &Connection| {
let res = crate::db::read::get_available_addrs(connection, account)?;
Ok(res)
};
to_cresult(with_coin(coin, res))
}
#[no_mangle]
pub unsafe extern "C" fn get_address(
coin: u8,
@ -507,9 +523,15 @@ pub async unsafe extern "C" fn shield_taddr(
#[tokio::main]
#[no_mangle]
pub async unsafe extern "C" fn scan_transparent_accounts(coin: u8, account: u32, gap_limit: u32) -> CResult<*const u8> {
pub async unsafe extern "C" fn scan_transparent_accounts(
coin: u8,
account: u32,
gap_limit: u32,
) -> CResult<*const u8> {
let res = async {
let addresses = crate::api::account::scan_transparent_accounts(coin, account, gap_limit as usize).await?;
let addresses =
crate::api::account::scan_transparent_accounts(coin, account, gap_limit as usize)
.await?;
let mut builder = FlatBufferBuilder::new();
let root = addresses.pack(&mut builder);
builder.finish(root, None);
@ -877,13 +899,6 @@ pub unsafe extern "C" fn clear_tx_details(coin: u8, account: u32) -> CResult<u8>
to_cresult(with_coin(coin, res))
}
fn with_coin<T, F: Fn(&Connection) -> anyhow::Result<T>>(coin: u8, f: F) -> anyhow::Result<T> {
let c = CoinConfig::get(coin);
let db = c.db()?;
let connection = &db.connection;
f(connection)
}
#[no_mangle]
pub unsafe extern "C" fn get_account_list(coin: u8) -> CResult<*const u8> {
let res = |connection: &Connection| {
@ -1142,10 +1157,7 @@ pub unsafe extern "C" fn clone_db_with_passwd(
}
#[no_mangle]
pub unsafe extern "C" fn get_property(
coin: u8,
name: *mut c_char,
) -> CResult<*mut c_char> {
pub unsafe extern "C" fn get_property(coin: u8, name: *mut c_char) -> CResult<*mut c_char> {
from_c_str!(name);
let res = |connection: &Connection| {
let value = crate::db::read::get_property(connection, &name)?;

View File

@ -1131,10 +1131,7 @@ impl DbAdapter {
"UPDATE transactions SET address = NULL, memo = NULL WHERE account = ?1",
[account],
)?;
connection.execute(
"DELETE FROM messages WHERE account = ?1",
[account],
)?;
connection.execute("DELETE FROM messages WHERE account = ?1", [account])?;
Ok(())
}

View File

@ -294,7 +294,8 @@ pub fn get_messages(network: &Network, connection: &Connection, id: u32) -> Resu
let mut stmt = connection.prepare(
"SELECT m.id, m.id_tx, m.timestamp, m.sender, m.recipient, m.incoming, \
subject, body, height, read FROM messages m \
WHERE account = ?1 ORDER BY timestamp DESC")?;
WHERE account = ?1 ORDER BY timestamp DESC",
)?;
let rows = stmt.query_map(params![id], |row| {
let id_msg: u32 = row.get("id")?;
let id_tx: Option<u32> = row.get("id_tx")?;
@ -329,7 +330,9 @@ pub fn get_messages(network: &Network, connection: &Connection, id: u32) -> Resu
for r in rows {
messages.push(r?);
}
let messages = MessageVecT { messages: Some(messages) };
let messages = MessageVecT {
messages: Some(messages),
};
Ok(messages)
}
@ -660,15 +663,48 @@ pub fn resolve_addresses(
}
pub fn get_property(connection: &Connection, name: &str) -> anyhow::Result<String> {
let url = connection.query_row("SELECT value FROM properties WHERE name = ?1", [name], |row| {
let url: String = row.get(0)?;
Ok(url)
}).optional()?;
let url = connection
.query_row(
"SELECT value FROM properties WHERE name = ?1",
[name],
|row| {
let url: String = row.get(0)?;
Ok(url)
},
)
.optional()?;
Ok(url.unwrap_or(String::new()))
}
pub fn set_property(connection: &Connection, name: &str, value: &str) -> anyhow::Result<()> {
connection.execute("INSERT INTO properties(name, value) VALUES (?1, ?2) ON CONFLICT (name) \
DO UPDATE SET value = excluded.value", params![name, value])?;
connection.execute(
"INSERT INTO properties(name, value) VALUES (?1, ?2) ON CONFLICT (name) \
DO UPDATE SET value = excluded.value",
params![name, value],
)?;
Ok(())
}
pub fn get_available_addrs(connection: &Connection, account: u32) -> anyhow::Result<u8> {
let has_transparent = connection
.query_row(
"SELECT 1 FROM taddrs WHERE account = ?1",
[account],
|_row| Ok(()),
)
.optional()?
.is_some();
let has_sapling = true;
let has_orchard = connection
.query_row(
"SELECT 1 FROM orchard_addrs WHERE account = ?1",
[account],
|_row| Ok(()),
)
.optional()?
.is_some();
let res = if has_transparent { 1 } else { 0 }
| if has_sapling { 2 } else { 0 }
| if has_orchard { 4 } else { 0 };
Ok(res)
}

View File

@ -1,14 +1,14 @@
use crate::api::payment_v2::build_tx_plan_with_utxos;
use crate::api::recipient::RecipientMemo;
use crate::chain::{get_checkpoint_height, EXPIRY_HEIGHT_OFFSET, get_latest_height};
use crate::chain::{get_checkpoint_height, get_latest_height, EXPIRY_HEIGHT_OFFSET};
use crate::coinconfig::CoinConfig;
use crate::db::AccountData;
use crate::key2::split_key;
use crate::note_selection::{SecretKeys, Source, UTXO};
use crate::unified::orchard_as_unified;
use crate::{
broadcast_tx, build_tx, AddressList, BlockId, CompactTxStreamerClient, GetAddressUtxosArg,
GetAddressUtxosReply, Hash, TransparentAddressBlockFilter, TxFilter, BlockRange,
broadcast_tx, build_tx, AddressList, BlockId, BlockRange, CompactTxStreamerClient,
GetAddressUtxosArg, GetAddressUtxosReply, Hash, TransparentAddressBlockFilter, TxFilter,
};
use anyhow::anyhow;
use base58check::FromBase58Check;
@ -25,7 +25,7 @@ use tonic::transport::Channel;
use tonic::Request;
use zcash_client_backend::encoding::encode_transparent_address;
use zcash_params::coin::get_branch;
use zcash_primitives::consensus::{Network, Parameters, NetworkUpgrade};
use zcash_primitives::consensus::{Network, NetworkUpgrade, Parameters};
use zcash_primitives::legacy::TransparentAddress;
use zcash_primitives::memo::Memo;
use zcash_primitives::transaction::components::OutPoint;
@ -178,12 +178,23 @@ pub async fn scan_transparent_accounts(
mut aindex: u32,
gap_limit: usize,
) -> anyhow::Result<Vec<TBalance>> {
let start: u32 = network.activation_height(NetworkUpgrade::Sapling).unwrap().into();
let start: u32 = network
.activation_height(NetworkUpgrade::Sapling)
.unwrap()
.into();
let end = get_latest_height(client).await?;
let range = BlockRange {
start: Some(BlockId { height: start as u64, hash: vec![] }),
end: Some(BlockId { height: end as u64, hash: vec![] }), spam_filter_threshold: 0 };
start: Some(BlockId {
height: start as u64,
hash: vec![],
}),
end: Some(BlockId {
height: end as u64,
hash: vec![],
}),
spam_filter_threshold: 0,
};
let mut addresses = vec![];
let mut gap = 0;