Lazy init prover

This commit is contained in:
Hanh 2021-09-22 09:08:27 +08:00
parent ccfd24256a
commit b8c41fe9b3
3 changed files with 26 additions and 10 deletions

View File

@ -56,6 +56,7 @@ lazy_static = "1.4.0"
rustyline = "8.2.0" rustyline = "8.2.0"
clap = "3.0.0-beta.2" clap = "3.0.0-beta.2"
chrono = "0.4.19" chrono = "0.4.19"
lazycell = "1.3.0"
reqwest = { version = "0.11.4", features = ["json", "rustls-tls"], default-features = false } reqwest = { version = "0.11.4", features = ["json", "rustls-tls"], default-features = false }
# librustzcash synced to 35023ed8ca2fb1061e78fd740b640d4eefcc5edd # librustzcash synced to 35023ed8ca2fb1061e78fd740b640d4eefcc5edd

View File

@ -108,7 +108,7 @@ mod tests {
println!("{:?}", m); println!("{:?}", m);
} }
let wallet = Wallet::new("zec.db", LWD_URL); let mut wallet = Wallet::new("zec.db", LWD_URL);
let tx_id = wallet.save_contacts_tx(&memos, 1, 3).await.unwrap(); let tx_id = wallet.save_contacts_tx(&memos, 1, 3).await.unwrap();
println!("{}", tx_id); println!("{}", tx_id);
} }

View File

@ -31,13 +31,14 @@ use zcash_proofs::prover::LocalTxProver;
use zcash_primitives::memo::Memo; use zcash_primitives::memo::Memo;
use std::str::FromStr; use std::str::FromStr;
use crate::contact::{Contact, serialize_contacts}; use crate::contact::{Contact, serialize_contacts};
use lazycell::AtomicLazyCell;
const DEFAULT_CHUNK_SIZE: u32 = 100_000; const DEFAULT_CHUNK_SIZE: u32 = 100_000;
pub struct Wallet { pub struct Wallet {
pub db_path: String, pub db_path: String,
db: DbAdapter, db: DbAdapter,
prover: LocalTxProver, prover: AtomicLazyCell<LocalTxProver>,
pub ld_url: String, pub ld_url: String,
} }
@ -83,13 +84,12 @@ impl From<&Recipient> for RecipientMemo {
impl Wallet { impl Wallet {
pub fn new(db_path: &str, ld_url: &str) -> Wallet { pub fn new(db_path: &str, ld_url: &str) -> Wallet {
let prover = LocalTxProver::from_bytes(SPEND_PARAMS, OUTPUT_PARAMS);
let db = DbAdapter::new(db_path).unwrap(); let db = DbAdapter::new(db_path).unwrap();
db.init_db().unwrap(); db.init_db().unwrap();
Wallet { Wallet {
db_path: db_path.to_string(), db_path: db_path.to_string(),
db, db,
prover, prover: AtomicLazyCell::new(),
ld_url: ld_url.to_string(), ld_url: ld_url.to_string(),
} }
} }
@ -336,8 +336,11 @@ impl Wallet {
Amount::zero()).await?; Amount::zero()).await?;
} }
self._ensure_prover()?;
let prover = self.prover.borrow().unwrap();
let consensus_branch_id = get_branch(last_height); let consensus_branch_id = get_branch(last_height);
let (tx, _) = builder.build(consensus_branch_id, &self.prover)?; let (tx, _) = builder.build(consensus_branch_id, prover)?;
log::info!("Tx built"); log::info!("Tx built");
let mut raw_tx: Vec<u8> = vec![]; let mut raw_tx: Vec<u8> = vec![];
tx.write(&mut raw_tx)?; tx.write(&mut raw_tx)?;
@ -354,6 +357,14 @@ impl Wallet {
Ok(tx_id) Ok(tx_id)
} }
fn _ensure_prover(&mut self) -> anyhow::Result<()> {
if !self.prover.filled() {
let prover = LocalTxProver::from_bytes(SPEND_PARAMS, OUTPUT_PARAMS);
self.prover.fill(prover).map_err(|_| anyhow::anyhow!("dup prover"))?;
}
Ok(())
}
pub fn get_ivk(&self, account: u32) -> anyhow::Result<String> { pub fn get_ivk(&self, account: u32) -> anyhow::Result<String> {
self.db.get_ivk(account) self.db.get_ivk(account)
} }
@ -385,8 +396,10 @@ impl Wallet {
Ok(balance) Ok(balance)
} }
pub async fn shield_taddr(&self, account: u32) -> anyhow::Result<String> { pub async fn shield_taddr(&mut self, account: u32) -> anyhow::Result<String> {
shield_taddr(&self.db, account, &self.prover, &self.ld_url).await self._ensure_prover()?;
let prover = self.prover.borrow().unwrap();
shield_taddr(&self.db, account, prover, &self.ld_url).await
} }
pub fn store_contact(&self, id: u32, name: &str, address: &str, dirty: bool) -> anyhow::Result<()> { pub fn store_contact(&self, id: u32, name: &str, address: &str, dirty: bool) -> anyhow::Result<()> {
@ -399,14 +412,14 @@ impl Wallet {
Ok(()) Ok(())
} }
pub async fn commit_unsaved_contacts(&self, account: u32, anchor_offset: u32) -> anyhow::Result<String> { pub async fn commit_unsaved_contacts(&mut self, account: u32, anchor_offset: u32) -> anyhow::Result<String> {
let contacts = self.db.get_unsaved_contacts()?; let contacts = self.db.get_unsaved_contacts()?;
let memos = serialize_contacts(&contacts)?; let memos = serialize_contacts(&contacts)?;
let tx_id = self.save_contacts_tx(&memos, account, anchor_offset).await.unwrap(); let tx_id = self.save_contacts_tx(&memos, account, anchor_offset).await.unwrap();
Ok(tx_id) Ok(tx_id)
} }
pub async fn save_contacts_tx(&self, memos: &[Memo], account: u32, anchor_offset: u32) -> anyhow::Result<String> { pub async fn save_contacts_tx(&mut self, memos: &[Memo], account: u32, anchor_offset: u32) -> anyhow::Result<String> {
let mut client = connect_lightwalletd(&self.ld_url).await?; let mut client = connect_lightwalletd(&self.ld_url).await?;
let last_height = get_latest_height(&mut client).await?; let last_height = get_latest_height(&mut client).await?;
@ -427,8 +440,10 @@ impl Wallet {
}).collect(); }).collect();
prepare_tx(&mut builder, Some(skey), &notes, DEFAULT_FEE, &extfvk, &recipients)?; prepare_tx(&mut builder, Some(skey), &notes, DEFAULT_FEE, &extfvk, &recipients)?;
self._ensure_prover()?;
let prover = self.prover.borrow().unwrap();
let consensus_branch_id = get_branch(last_height); let consensus_branch_id = get_branch(last_height);
let (tx, _) = builder.build(consensus_branch_id, &self.prover)?; let (tx, _) = builder.build(consensus_branch_id, prover)?;
let mut raw_tx: Vec<u8> = vec![]; let mut raw_tx: Vec<u8> = vec![];
tx.write(&mut raw_tx)?; tx.write(&mut raw_tx)?;