Fix Scan TAddrs

This commit is contained in:
Hanh 2023-03-13 17:49:15 +10:00
parent 09f2c10930
commit ee76725695
4 changed files with 62 additions and 63 deletions

View File

@ -271,7 +271,9 @@ struct CResult_____c_char shield_taddr(uint8_t coin,
uint64_t amount,
uint32_t confirmations);
struct CResult______u8 scan_transparent_accounts(uint32_t gap_limit);
struct CResult______u8 scan_transparent_accounts(uint8_t coin,
uint32_t account,
uint32_t gap_limit);
struct CResult_____c_char prepare_multi_payment(uint8_t coin,
uint32_t account,

View File

@ -4,7 +4,7 @@
use crate::coinconfig::CoinConfig;
use crate::db::data_generated::fb::{
AddressBalance, AddressBalanceArgs, AddressBalanceVec, AddressBalanceVecArgs, BackupT, KeyPackT,
BackupT, KeyPackT, AddressBalanceVecT, AddressBalanceT,
};
use crate::db::AccountData;
use crate::key2::decode_key;
@ -265,35 +265,24 @@ 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(gap_limit: usize) -> anyhow::Result<Vec<u8>> {
let c = CoinConfig::get_active();
let mut client = c.connect_lwd().await?;
let addresses =
crate::taddr::scan_transparent_accounts(c.chain.network(), &mut client, gap_limit).await?;
let mut builder = flatbuffers::FlatBufferBuilder::new();
let mut addrs = vec![];
for a in addresses {
let address = builder.create_string(&a.address);
let ab = AddressBalance::create(
&mut builder,
&AddressBalanceArgs {
index: a.index,
address: Some(address),
balance: a.balance,
},
);
addrs.push(ab);
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 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?);
}
let addrs = builder.create_vector(&addrs);
let addrs = AddressBalanceVec::create(
&mut builder,
&AddressBalanceVecArgs {
values: Some(addrs),
},
);
builder.finish(addrs, None);
let data = builder.finished_data().to_vec();
Ok(data)
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)
};
Ok(addresses)
}
/// Get the backup string. It is either the passphrase, the secret key or the viewing key

View File

@ -507,9 +507,15 @@ pub async unsafe extern "C" fn shield_taddr(
#[tokio::main]
#[no_mangle]
pub async unsafe extern "C" fn scan_transparent_accounts(gap_limit: u32) -> CResult<*const u8> {
let res = crate::api::account::scan_transparent_accounts(gap_limit as usize).await;
to_cresult_bytes(res)
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 mut builder = FlatBufferBuilder::new();
let root = addresses.pack(&mut builder);
builder.finish(root, None);
Ok(builder.finished_data().to_vec())
};
to_cresult_bytes(res.await)
}
#[tokio::main]

View File

@ -1,6 +1,6 @@
use crate::api::payment_v2::build_tx_plan_with_utxos;
use crate::api::recipient::RecipientMemo;
use crate::chain::{get_checkpoint_height, EXPIRY_HEIGHT_OFFSET};
use crate::chain::{get_checkpoint_height, EXPIRY_HEIGHT_OFFSET, get_latest_height};
use crate::coinconfig::CoinConfig;
use crate::db::AccountData;
use crate::key2::split_key;
@ -8,7 +8,7 @@ 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,
GetAddressUtxosReply, Hash, TransparentAddressBlockFilter, TxFilter, BlockRange,
};
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};
use zcash_primitives::consensus::{Network, Parameters, NetworkUpgrade};
use zcash_primitives::legacy::TransparentAddress;
use zcash_primitives::memo::Memo;
use zcash_primitives::transaction::components::OutPoint;
@ -141,10 +141,11 @@ pub async fn get_ttx_history(
pub async fn get_taddr_tx_count(
client: &mut CompactTxStreamerClient<Channel>,
address: &str,
range: &BlockRange,
) -> anyhow::Result<u32> {
let req = TransparentAddressBlockFilter {
address: address.to_string(),
range: None,
range: Some(range.clone()),
};
let rep = client
.get_taddress_txids(Request::new(req))
@ -173,39 +174,40 @@ pub async fn get_utxos(
pub async fn scan_transparent_accounts(
network: &Network,
client: &mut CompactTxStreamerClient<Channel>,
seed: &str,
mut aindex: u32,
gap_limit: usize,
) -> anyhow::Result<Vec<TBalance>> {
let c = CoinConfig::get_active();
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 };
let mut addresses = vec![];
let db = c.db()?;
let account_data = db.get_account_info(c.id_account)?;
let AccountData {
seed, mut aindex, ..
} = account_data;
if let Some(seed) = seed {
let mut gap = 0;
while gap < gap_limit {
let bip44_path = format!("m/44'/{}'/0'/0/{}", network.coin_type(), aindex);
log::info!("{} {}", aindex, bip44_path);
let (_, address) = derive_tkeys(network, &seed, &bip44_path)?;
let balance = get_taddr_balance(client, &address).await?;
if balance > 0 {
addresses.push(TBalance {
index: aindex,
address,
balance,
});
let mut gap = 0;
while gap < gap_limit {
let bip44_path = format!("m/44'/{}'/0'/0/{}", network.coin_type(), aindex);
log::info!("{} {}", aindex, bip44_path);
let (_, address) = derive_tkeys(network, &seed, &bip44_path)?;
let balance = get_taddr_balance(client, &address).await?;
if balance > 0 {
addresses.push(TBalance {
index: aindex,
address,
balance,
});
gap = 0;
} else {
let tx_count = get_taddr_tx_count(client, &address, &range).await?;
if tx_count != 0 {
gap = 0;
} else {
let tx_count = get_taddr_tx_count(client, &address).await?;
if tx_count != 0 {
gap = 0;
} else {
gap += 1;
}
gap += 1;
}
aindex += 1;
}
aindex += 1;
}
Ok(addresses)
}