2022-10-19 23:24:36 -07:00
|
|
|
use crate::chain::{DecryptedBlock, get_latest_height, Nf, NfRef};
|
2022-09-04 04:19:49 -07:00
|
|
|
use crate::db::{AccountViewKey, DbAdapter, PlainNote, ReceivedNote};
|
2022-10-04 20:22:04 -07:00
|
|
|
use serde::Serialize;
|
2022-08-16 07:47:48 -07:00
|
|
|
use std::cmp::Ordering;
|
2022-07-21 18:08:29 -07:00
|
|
|
|
2021-07-16 01:42:29 -07:00
|
|
|
use crate::transaction::retrieve_tx_info;
|
2022-09-05 08:05:55 -07:00
|
|
|
use crate::{
|
2022-10-19 23:24:36 -07:00
|
|
|
connect_lightwalletd, CompactBlock, CompactSaplingOutput,
|
|
|
|
CompactTx
|
2022-09-05 08:05:55 -07:00
|
|
|
};
|
2022-10-19 23:24:36 -07:00
|
|
|
use crate::chain::{DecryptNode, download_chain};
|
2021-06-21 17:33:13 -07:00
|
|
|
use ff::PrimeField;
|
2022-07-21 18:08:29 -07:00
|
|
|
|
2022-09-05 08:05:55 -07:00
|
|
|
use anyhow::anyhow;
|
2022-08-21 09:40:14 -07:00
|
|
|
use lazy_static::lazy_static;
|
2021-09-12 21:08:31 -07:00
|
|
|
use std::collections::HashMap;
|
2021-07-16 01:42:29 -07:00
|
|
|
use std::panic;
|
2021-06-24 05:08:20 -07:00
|
|
|
use std::sync::Arc;
|
2021-06-26 02:52:03 -07:00
|
|
|
use std::time::Instant;
|
2022-08-17 18:23:23 -07:00
|
|
|
use tokio::runtime::{Builder, Runtime};
|
2021-06-26 02:52:03 -07:00
|
|
|
use tokio::sync::mpsc;
|
2021-06-24 05:08:20 -07:00
|
|
|
use tokio::sync::Mutex;
|
2022-09-04 04:19:49 -07:00
|
|
|
use zcash_client_backend::encoding::decode_extended_full_viewing_key;
|
2022-06-07 09:58:24 -07:00
|
|
|
use zcash_params::coin::{get_coin_chain, CoinType};
|
2022-09-05 08:05:55 -07:00
|
|
|
use zcash_primitives::consensus::{Network, Parameters};
|
2021-06-18 01:17:41 -07:00
|
|
|
|
2022-09-04 04:19:49 -07:00
|
|
|
use zcash_primitives::sapling::{Node, Note};
|
2021-06-18 01:17:41 -07:00
|
|
|
|
2022-10-04 20:22:04 -07:00
|
|
|
pub struct Blocks(pub Vec<CompactBlock>, pub usize);
|
2021-06-21 17:33:13 -07:00
|
|
|
|
2022-08-17 18:23:23 -07:00
|
|
|
lazy_static! {
|
|
|
|
static ref DECRYPTER_RUNTIME: Runtime = Builder::new_multi_thread().build().unwrap();
|
|
|
|
}
|
|
|
|
|
2021-07-27 22:07:20 -07:00
|
|
|
#[derive(Debug)]
|
|
|
|
struct TxIdSet(Vec<u32>);
|
|
|
|
|
2021-06-21 17:33:13 -07:00
|
|
|
impl std::fmt::Debug for Blocks {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
write!(f, "Blocks of len {}", self.0.len())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-04 20:22:04 -07:00
|
|
|
#[derive(Clone, Serialize)]
|
|
|
|
pub struct Progress {
|
2022-10-19 23:24:36 -07:00
|
|
|
pub height: u32,
|
|
|
|
pub trial_decryptions: u64,
|
|
|
|
pub downloaded: usize,
|
2022-10-04 20:22:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pub type ProgressCallback = dyn Fn(Progress) + Send;
|
2022-06-08 05:48:16 -07:00
|
|
|
pub type AMProgressCallback = Arc<Mutex<ProgressCallback>>;
|
2021-06-21 17:33:13 -07:00
|
|
|
|
2021-08-10 04:51:39 -07:00
|
|
|
#[derive(PartialEq, PartialOrd, Debug, Hash, Eq)]
|
|
|
|
pub struct TxIdHeight {
|
2021-09-12 21:08:31 -07:00
|
|
|
id_tx: u32,
|
2021-08-10 04:51:39 -07:00
|
|
|
height: u32,
|
|
|
|
index: u32,
|
|
|
|
}
|
|
|
|
|
2021-06-26 02:52:03 -07:00
|
|
|
pub async fn sync_async(
|
2022-03-07 06:47:06 -08:00
|
|
|
coin_type: CoinType,
|
2022-07-14 18:12:25 -07:00
|
|
|
_chunk_size: u32,
|
2021-07-09 22:44:13 -07:00
|
|
|
get_tx: bool,
|
2021-06-26 02:52:03 -07:00
|
|
|
db_path: &str,
|
|
|
|
target_height_offset: u32,
|
2022-07-30 16:11:58 -07:00
|
|
|
max_cost: u32,
|
2022-06-08 05:48:16 -07:00
|
|
|
progress_callback: AMProgressCallback,
|
2022-08-30 07:00:15 -07:00
|
|
|
cancel: &'static std::sync::Mutex<bool>,
|
2021-07-16 01:42:29 -07:00
|
|
|
ld_url: &str,
|
2021-06-26 02:52:03 -07:00
|
|
|
) -> anyhow::Result<()> {
|
2021-07-09 06:33:05 -07:00
|
|
|
let ld_url = ld_url.to_owned();
|
2021-06-21 17:33:13 -07:00
|
|
|
let db_path = db_path.to_string();
|
2022-03-07 06:47:06 -08:00
|
|
|
let network = {
|
|
|
|
let chain = get_coin_chain(coin_type);
|
2022-06-08 05:48:16 -07:00
|
|
|
*chain.network()
|
2022-03-07 06:47:06 -08:00
|
|
|
};
|
2021-06-21 17:33:13 -07:00
|
|
|
|
2021-07-09 06:33:05 -07:00
|
|
|
let mut client = connect_lightwalletd(&ld_url).await?;
|
2022-07-09 09:12:34 -07:00
|
|
|
let (start_height, prev_hash, vks) = {
|
2022-09-04 04:19:49 -07:00
|
|
|
let db = DbAdapter::new(coin_type, &db_path)?;
|
2021-06-26 02:52:03 -07:00
|
|
|
let height = db.get_db_height()?;
|
2021-06-29 00:04:12 -07:00
|
|
|
let hash = db.get_db_hash(height)?;
|
2021-07-27 22:07:20 -07:00
|
|
|
let vks = db.get_fvks()?;
|
|
|
|
(height, hash, vks)
|
2021-06-24 05:08:20 -07:00
|
|
|
};
|
2022-09-02 01:44:31 -07:00
|
|
|
|
2021-06-21 17:33:13 -07:00
|
|
|
let end_height = get_latest_height(&mut client).await?;
|
2021-06-24 05:08:20 -07:00
|
|
|
let end_height = (end_height - target_height_offset).max(start_height);
|
2022-07-13 21:21:20 -07:00
|
|
|
if start_height >= end_height {
|
|
|
|
return Ok(());
|
|
|
|
}
|
2022-08-03 08:30:34 -07:00
|
|
|
let n_ivks = vks.len();
|
2021-06-21 17:33:13 -07:00
|
|
|
|
2022-09-01 07:30:42 -07:00
|
|
|
let decrypter = DecryptNode::new(vks);
|
2021-06-29 00:04:12 -07:00
|
|
|
|
2022-08-17 18:23:23 -07:00
|
|
|
let (decryptor_tx, mut decryptor_rx) = mpsc::channel::<Blocks>(1);
|
2022-10-04 20:22:04 -07:00
|
|
|
let (processor_tx, mut processor_rx) = mpsc::channel::<(Vec<DecryptedBlock>, usize)>(1);
|
2021-06-21 17:33:13 -07:00
|
|
|
|
2021-07-27 22:07:20 -07:00
|
|
|
let db_path2 = db_path.clone();
|
|
|
|
|
2021-06-24 05:08:20 -07:00
|
|
|
let downloader = tokio::spawn(async move {
|
2022-07-09 09:12:34 -07:00
|
|
|
log::info!("download_scheduler");
|
|
|
|
download_chain(
|
|
|
|
&mut client,
|
2022-08-03 08:30:34 -07:00
|
|
|
n_ivks,
|
2022-07-09 09:12:34 -07:00
|
|
|
start_height,
|
|
|
|
end_height,
|
|
|
|
prev_hash,
|
2022-08-31 08:35:21 -07:00
|
|
|
max_cost,
|
2022-08-17 18:23:23 -07:00
|
|
|
decryptor_tx,
|
2022-07-21 18:08:29 -07:00
|
|
|
cancel,
|
2022-07-09 09:12:34 -07:00
|
|
|
)
|
|
|
|
.await?;
|
2021-06-24 05:08:20 -07:00
|
|
|
Ok::<_, anyhow::Error>(())
|
2021-06-21 17:33:13 -07:00
|
|
|
});
|
|
|
|
|
2021-06-24 05:08:20 -07:00
|
|
|
let proc_callback = progress_callback.clone();
|
|
|
|
|
2022-08-17 18:23:23 -07:00
|
|
|
let decryptor = DECRYPTER_RUNTIME.spawn(async move {
|
|
|
|
while let Some(blocks) = decryptor_rx.recv().await {
|
|
|
|
let dec_blocks = decrypter.decrypt_blocks(&network, blocks.0); // this function may block
|
|
|
|
let batch_decrypt_elapsed: usize = dec_blocks.iter().map(|b| b.elapsed).sum();
|
|
|
|
log::info!(" Batch Decrypt: {} ms", batch_decrypt_elapsed);
|
2022-10-04 20:22:04 -07:00
|
|
|
let _ = processor_tx.send((dec_blocks, blocks.1)).await;
|
2022-08-17 18:23:23 -07:00
|
|
|
}
|
|
|
|
Ok::<_, anyhow::Error>(())
|
|
|
|
});
|
|
|
|
|
2022-10-04 20:22:04 -07:00
|
|
|
let mut progress = Progress {
|
|
|
|
height: 0,
|
|
|
|
trial_decryptions: 0,
|
|
|
|
downloaded: 0,
|
|
|
|
};
|
|
|
|
|
2021-06-24 05:08:20 -07:00
|
|
|
let processor = tokio::spawn(async move {
|
2022-04-19 09:47:08 -07:00
|
|
|
let mut db = DbAdapter::new(coin_type, &db_path2)?;
|
2021-06-24 05:08:20 -07:00
|
|
|
let mut nfs = db.get_nullifiers()?;
|
|
|
|
|
2022-10-04 20:22:04 -07:00
|
|
|
while let Some((dec_blocks, blocks_size)) = processor_rx.recv().await {
|
2022-08-17 18:23:23 -07:00
|
|
|
if dec_blocks.is_empty() {
|
2021-06-26 02:52:03 -07:00
|
|
|
continue;
|
|
|
|
}
|
2022-10-04 20:22:04 -07:00
|
|
|
progress.downloaded += blocks_size;
|
2022-10-22 19:34:50 -07:00
|
|
|
let (mut sapling_checkpoint, mut orchard_checkpoint) = db.get_tree()?;
|
2022-10-23 03:29:07 -07:00
|
|
|
/* TODO
|
|
|
|
- Change to WarpProcessors & Trial Decryptors - sapling & orchard
|
|
|
|
- Feed block into WP sapling
|
|
|
|
- Check height vs orchard activation height -> Feed block into WP orchard
|
|
|
|
- Refactor into function
|
|
|
|
- Remove new_idtx
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2022-07-09 01:26:25 -07:00
|
|
|
let mut bp = BlockProcessor::new(&tree, &witnesses);
|
|
|
|
let mut absolute_position_at_block_start = tree.get_position();
|
|
|
|
|
2022-08-17 18:23:23 -07:00
|
|
|
log::info!("start processing - {}", dec_blocks[0].height);
|
2022-03-14 05:50:56 -07:00
|
|
|
log::info!("Time {:?}", chrono::offset::Local::now());
|
|
|
|
let start = Instant::now();
|
2021-06-21 17:33:13 -07:00
|
|
|
|
2021-09-12 21:08:31 -07:00
|
|
|
let mut new_ids_tx: HashMap<u32, TxIdHeight> = HashMap::new();
|
2021-06-26 02:52:03 -07:00
|
|
|
let mut witnesses: Vec<Witness> = vec![];
|
2021-09-02 19:56:10 -07:00
|
|
|
|
2021-11-11 17:39:50 -08:00
|
|
|
{
|
|
|
|
// db tx scope
|
2021-09-02 19:56:10 -07:00
|
|
|
let db_tx = db.begin_transaction()?;
|
2022-08-16 07:47:48 -07:00
|
|
|
let outputs = dec_blocks
|
|
|
|
.iter()
|
|
|
|
.map(|db| db.count_outputs as usize)
|
|
|
|
.sum::<usize>();
|
2022-08-30 07:00:15 -07:00
|
|
|
{
|
2022-10-04 20:22:04 -07:00
|
|
|
progress.trial_decryptions += (n_ivks * outputs) as u64;
|
2022-08-30 07:00:15 -07:00
|
|
|
}
|
2021-09-02 19:56:10 -07:00
|
|
|
for b in dec_blocks.iter() {
|
|
|
|
let mut my_nfs: Vec<Nf> = vec![];
|
|
|
|
for nf in b.spends.iter() {
|
|
|
|
if let Some(&nf_ref) = nfs.get(nf) {
|
|
|
|
log::info!("NF FOUND {} {}", nf_ref.id_note, b.height);
|
|
|
|
DbAdapter::mark_spent(nf_ref.id_note, b.height, &db_tx)?;
|
|
|
|
my_nfs.push(*nf);
|
|
|
|
nfs.remove(nf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !b.notes.is_empty() {
|
|
|
|
log::debug!("{} {}", b.height, b.notes.len());
|
2021-06-24 05:08:20 -07:00
|
|
|
}
|
2021-06-26 02:52:03 -07:00
|
|
|
|
2021-09-02 19:56:10 -07:00
|
|
|
for n in b.notes.iter() {
|
|
|
|
let p = absolute_position_at_block_start + n.position_in_block;
|
|
|
|
|
|
|
|
let note = &n.note;
|
|
|
|
let rcm = note.rcm().to_repr();
|
2022-10-21 21:01:29 -07:00
|
|
|
let nf = note.nf(&n.ivk.fvk.vk.nk, p as u64);
|
2021-09-02 19:56:10 -07:00
|
|
|
|
|
|
|
let id_tx = DbAdapter::store_transaction(
|
|
|
|
&n.txid,
|
|
|
|
n.account,
|
|
|
|
n.height,
|
|
|
|
b.compact_block.time,
|
|
|
|
n.tx_index as u32,
|
|
|
|
&db_tx,
|
|
|
|
)?;
|
2021-11-11 17:39:50 -08:00
|
|
|
new_ids_tx.insert(
|
2021-09-12 21:08:31 -07:00
|
|
|
id_tx,
|
2021-11-11 17:39:50 -08:00
|
|
|
TxIdHeight {
|
|
|
|
id_tx,
|
|
|
|
height: n.height,
|
|
|
|
index: n.tx_index as u32,
|
|
|
|
},
|
|
|
|
);
|
2021-09-02 19:56:10 -07:00
|
|
|
let id_note = DbAdapter::store_received_note(
|
|
|
|
&ReceivedNote {
|
|
|
|
account: n.account,
|
|
|
|
height: n.height,
|
|
|
|
output_index: n.output_index as u32,
|
|
|
|
diversifier: n.pa.diversifier().0.to_vec(),
|
|
|
|
value: note.value,
|
|
|
|
rcm: rcm.to_vec(),
|
2022-10-19 23:32:11 -07:00
|
|
|
rho: None,
|
2021-09-02 19:56:10 -07:00
|
|
|
nf: nf.0.to_vec(),
|
|
|
|
spent: None,
|
|
|
|
},
|
|
|
|
id_tx,
|
|
|
|
n.position_in_block,
|
2021-11-11 17:39:50 -08:00
|
|
|
&db_tx,
|
2021-09-02 19:56:10 -07:00
|
|
|
)?;
|
|
|
|
DbAdapter::add_value(id_tx, note.value as i64, &db_tx)?;
|
|
|
|
nfs.insert(
|
|
|
|
Nf(nf.0),
|
|
|
|
NfRef {
|
|
|
|
id_note,
|
|
|
|
account: n.account,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
let w = Witness::new(p as usize, id_note, Some(n.clone()));
|
|
|
|
witnesses.push(w);
|
|
|
|
}
|
2021-06-26 02:52:03 -07:00
|
|
|
|
2021-09-12 19:53:54 -07:00
|
|
|
if !my_nfs.is_empty() {
|
2021-09-02 19:56:10 -07:00
|
|
|
for (tx_index, tx) in b.compact_block.vtx.iter().enumerate() {
|
|
|
|
for cs in tx.spends.iter() {
|
|
|
|
let mut nf = [0u8; 32];
|
|
|
|
nf.copy_from_slice(&cs.nf);
|
|
|
|
let nf = Nf(nf);
|
|
|
|
if my_nfs.contains(&nf) {
|
2021-11-11 17:39:50 -08:00
|
|
|
let (account, note_value) =
|
|
|
|
DbAdapter::get_received_note_value(&nf, &db_tx)?;
|
2021-09-02 19:56:10 -07:00
|
|
|
let txid = &*tx.hash;
|
|
|
|
let id_tx = DbAdapter::store_transaction(
|
|
|
|
txid,
|
|
|
|
account,
|
|
|
|
b.height,
|
|
|
|
b.compact_block.time,
|
|
|
|
tx_index as u32,
|
2021-11-11 17:39:50 -08:00
|
|
|
&db_tx,
|
2021-09-02 19:56:10 -07:00
|
|
|
)?;
|
2021-11-11 17:39:50 -08:00
|
|
|
new_ids_tx.insert(
|
2021-09-12 21:08:31 -07:00
|
|
|
id_tx,
|
2021-11-11 17:39:50 -08:00
|
|
|
TxIdHeight {
|
|
|
|
id_tx,
|
|
|
|
height: b.height,
|
|
|
|
index: tx_index as u32,
|
|
|
|
},
|
|
|
|
);
|
2021-09-02 19:56:10 -07:00
|
|
|
DbAdapter::add_value(id_tx, -(note_value as i64), &db_tx)?;
|
2021-08-10 04:51:39 -07:00
|
|
|
}
|
2021-06-26 02:52:03 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-09-02 19:56:10 -07:00
|
|
|
|
|
|
|
absolute_position_at_block_start += b.count_outputs as usize;
|
2021-06-26 02:52:03 -07:00
|
|
|
}
|
2021-09-02 19:56:10 -07:00
|
|
|
log::info!("Dec end : {}", start.elapsed().as_millis());
|
2021-06-26 02:52:03 -07:00
|
|
|
|
2021-09-02 19:56:10 -07:00
|
|
|
db_tx.commit()?;
|
2021-06-21 17:33:13 -07:00
|
|
|
}
|
|
|
|
|
2021-07-27 22:07:20 -07:00
|
|
|
let start = Instant::now();
|
2021-06-21 17:33:13 -07:00
|
|
|
let mut nodes: Vec<Node> = vec![];
|
2022-08-17 18:23:23 -07:00
|
|
|
for block in dec_blocks.iter() {
|
|
|
|
let cb = &block.compact_block;
|
2021-06-21 17:33:13 -07:00
|
|
|
for tx in cb.vtx.iter() {
|
|
|
|
for co in tx.outputs.iter() {
|
|
|
|
let mut cmu = [0u8; 32];
|
|
|
|
cmu.copy_from_slice(&co.cmu);
|
|
|
|
let node = Node::new(cmu);
|
|
|
|
nodes.push(node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-26 02:52:03 -07:00
|
|
|
if !nodes.is_empty() {
|
|
|
|
bp.add_nodes(&mut nodes, &witnesses);
|
|
|
|
}
|
2021-06-28 21:49:00 -07:00
|
|
|
// println!("NOTES = {}", nodes.len());
|
2021-06-21 17:33:13 -07:00
|
|
|
|
2021-07-27 22:07:20 -07:00
|
|
|
log::info!("Witness : {}", start.elapsed().as_millis());
|
|
|
|
|
|
|
|
let start = Instant::now();
|
2021-09-11 23:21:34 -07:00
|
|
|
if get_tx && !new_ids_tx.is_empty() {
|
2021-11-11 17:39:50 -08:00
|
|
|
let mut ids: Vec<_> = new_ids_tx.into_iter().map(|(_, v)| v).collect();
|
2021-09-12 21:08:31 -07:00
|
|
|
ids.sort_by(|a, b| {
|
|
|
|
let c = a.height.cmp(&b.height);
|
|
|
|
if c == Ordering::Equal {
|
|
|
|
return a.index.cmp(&b.index);
|
|
|
|
}
|
2022-06-08 05:48:16 -07:00
|
|
|
c
|
2021-09-12 21:08:31 -07:00
|
|
|
});
|
|
|
|
let ids: Vec<_> = ids.into_iter().map(|e| e.id_tx).collect();
|
2022-07-09 09:12:34 -07:00
|
|
|
let mut client = connect_lightwalletd(&ld_url).await?;
|
2022-09-01 07:30:42 -07:00
|
|
|
retrieve_tx_info(coin_type, &mut client, &db_path2, &ids).await?;
|
2021-07-27 22:07:20 -07:00
|
|
|
}
|
|
|
|
log::info!("Transaction Details : {}", start.elapsed().as_millis());
|
|
|
|
|
2022-07-09 01:26:25 -07:00
|
|
|
let (new_tree, new_witnesses) = bp.finalize();
|
|
|
|
tree = new_tree;
|
|
|
|
witnesses = new_witnesses;
|
2021-06-21 17:33:13 -07:00
|
|
|
|
2022-08-17 18:23:23 -07:00
|
|
|
if let Some(dec_block) = dec_blocks.last() {
|
2022-07-16 20:23:56 -07:00
|
|
|
{
|
2022-08-17 18:23:23 -07:00
|
|
|
let block = &dec_block.compact_block;
|
2022-07-16 20:23:56 -07:00
|
|
|
let mut db_transaction = db.begin_transaction()?;
|
|
|
|
let height = block.height as u32;
|
|
|
|
for w in witnesses.iter() {
|
|
|
|
DbAdapter::store_witnesses(&db_transaction, w, height, w.id_note)?;
|
|
|
|
}
|
|
|
|
DbAdapter::store_block(
|
|
|
|
&mut db_transaction,
|
|
|
|
height,
|
|
|
|
&block.hash,
|
|
|
|
block.time,
|
|
|
|
&tree,
|
2022-10-19 23:32:11 -07:00
|
|
|
None,
|
2022-07-16 20:23:56 -07:00
|
|
|
)?;
|
|
|
|
db_transaction.commit()?;
|
|
|
|
// db_transaction is dropped here
|
2022-07-09 01:26:25 -07:00
|
|
|
}
|
2022-10-19 23:24:36 -07:00
|
|
|
progress.height = dec_block.height;
|
|
|
|
log::info!("progress: {}", progress.height);
|
2022-07-16 20:23:56 -07:00
|
|
|
let callback = proc_callback.lock().await;
|
2022-10-04 20:22:04 -07:00
|
|
|
callback(progress.clone());
|
2021-06-24 05:08:20 -07:00
|
|
|
}
|
2021-06-21 17:33:13 -07:00
|
|
|
}
|
|
|
|
|
2021-06-26 02:52:03 -07:00
|
|
|
let callback = progress_callback.lock().await;
|
2022-10-04 20:22:04 -07:00
|
|
|
callback(progress);
|
2021-06-24 05:08:20 -07:00
|
|
|
|
2021-07-16 01:42:29 -07:00
|
|
|
db.purge_old_witnesses(end_height - 100)?;
|
2021-07-27 22:07:20 -07:00
|
|
|
|
2021-06-24 05:08:20 -07:00
|
|
|
Ok::<_, anyhow::Error>(())
|
2021-06-21 17:33:13 -07:00
|
|
|
});
|
|
|
|
|
2022-08-18 21:07:55 -07:00
|
|
|
let res = tokio::try_join!(downloader, decryptor, processor);
|
2021-06-24 05:08:20 -07:00
|
|
|
match res {
|
2022-08-18 21:07:55 -07:00
|
|
|
Ok((d, dc, p)) => {
|
2021-06-26 02:52:03 -07:00
|
|
|
if let Err(err) = d {
|
|
|
|
log::info!("Downloader error = {}", err);
|
|
|
|
return Err(err);
|
|
|
|
}
|
2022-08-18 21:07:55 -07:00
|
|
|
if let Err(err) = dc {
|
|
|
|
log::info!("Decryptor error = {}", err);
|
|
|
|
return Err(err);
|
|
|
|
}
|
2021-06-26 02:52:03 -07:00
|
|
|
if let Err(err) = p {
|
|
|
|
log::info!("Processor error = {}", err);
|
|
|
|
return Err(err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
log::info!("Sync error = {}", err);
|
2021-06-28 21:49:00 -07:00
|
|
|
if err.is_panic() {
|
|
|
|
panic::resume_unwind(err.into_panic());
|
|
|
|
}
|
2021-06-26 02:52:03 -07:00
|
|
|
anyhow::bail!("Join Error");
|
2021-07-16 01:42:29 -07:00
|
|
|
}
|
2021-06-24 05:08:20 -07:00
|
|
|
}
|
|
|
|
|
2021-06-26 02:52:03 -07:00
|
|
|
log::info!("Sync completed");
|
|
|
|
|
2021-06-21 17:33:13 -07:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2021-07-09 06:33:05 -07:00
|
|
|
pub async fn latest_height(ld_url: &str) -> anyhow::Result<u32> {
|
|
|
|
let mut client = connect_lightwalletd(ld_url).await?;
|
2021-06-24 05:08:20 -07:00
|
|
|
let height = get_latest_height(&mut client).await?;
|
|
|
|
Ok(height)
|
2021-06-21 17:33:13 -07:00
|
|
|
}
|
2022-09-04 04:19:49 -07:00
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
// test function
|
2022-09-05 08:05:55 -07:00
|
|
|
pub fn trial_decrypt_one(
|
|
|
|
network: &Network,
|
|
|
|
height: u32,
|
|
|
|
fvk: &str,
|
|
|
|
cmu: &[u8],
|
|
|
|
epk: &[u8],
|
|
|
|
ciphertext: &[u8],
|
|
|
|
) -> anyhow::Result<Option<Note>> {
|
2022-09-04 04:19:49 -07:00
|
|
|
let mut vks = HashMap::new();
|
2022-09-05 08:05:55 -07:00
|
|
|
let fvk =
|
2022-10-21 21:01:29 -07:00
|
|
|
decode_extended_full_viewing_key(network.hrp_sapling_extended_full_viewing_key(), &fvk)
|
|
|
|
.map_err(|e| anyhow!("Bech32 Decode Error"))?;
|
2022-09-04 04:19:49 -07:00
|
|
|
let ivk = fvk.fvk.vk.ivk();
|
2022-09-05 08:05:55 -07:00
|
|
|
vks.insert(
|
|
|
|
0,
|
|
|
|
AccountViewKey {
|
|
|
|
fvk,
|
|
|
|
ivk,
|
|
|
|
viewonly: false,
|
|
|
|
},
|
|
|
|
);
|
2022-09-04 04:19:49 -07:00
|
|
|
let dn = DecryptNode::new(vks);
|
|
|
|
let block = vec![CompactBlock {
|
|
|
|
proto_version: 0, // don't care about most of these fields
|
|
|
|
height: height as u64,
|
|
|
|
hash: vec![],
|
|
|
|
prev_hash: vec![],
|
|
|
|
time: 0,
|
|
|
|
header: vec![],
|
2022-09-05 08:05:55 -07:00
|
|
|
vtx: vec![CompactTx {
|
|
|
|
index: 0,
|
|
|
|
hash: vec![],
|
|
|
|
fee: 0,
|
|
|
|
spends: vec![],
|
|
|
|
actions: vec![],
|
|
|
|
outputs: vec![CompactSaplingOutput {
|
|
|
|
cmu: cmu.to_vec(),
|
|
|
|
epk: epk.to_vec(),
|
|
|
|
ciphertext: ciphertext.to_vec(),
|
|
|
|
}],
|
|
|
|
}],
|
2022-09-04 04:19:49 -07:00
|
|
|
}];
|
|
|
|
let decrypted_block = dn.decrypt_blocks(network, block);
|
|
|
|
let decrypted_block = decrypted_block.first().unwrap();
|
|
|
|
let note = decrypted_block.notes.first().map(|dn| dn.note.clone());
|
|
|
|
Ok(note)
|
2022-09-05 08:05:55 -07:00
|
|
|
}
|