This commit is contained in:
Hanh 2021-07-18 23:57:43 +08:00
parent ac0673aabd
commit 653cc44a49
4 changed files with 54 additions and 20 deletions

View File

@ -1,12 +1,11 @@
use crate::chain::{Nf, NfRef};
use crate::db::migration::{get_schema_version, update_schema_version};
use crate::taddr::{derive_tkeys, BIP44_PATH};
use crate::transaction::TransactionInfo;
use crate::transaction::{TransactionInfo, Contact};
use crate::{CTree, Witness};
use rusqlite::{params, Connection, OptionalExtension, NO_PARAMS};
use std::collections::HashMap;
use zcash_primitives::consensus::{NetworkUpgrade, Parameters};
use zcash_primitives::memo::Memo;
use zcash_primitives::merkle_tree::IncrementalWitness;
use zcash_primitives::sapling::{Diversifier, Node, Note, Rseed};
use zcash_primitives::zip32::{DiversifierIndex, ExtendedFullViewingKey};
@ -53,11 +52,8 @@ impl DbAdapter {
)?;
let version = get_schema_version(&self.connection)?;
if version == 2 {
return Ok(());
}
if version <= 0 {
if version < 1 {
self.connection.execute(
"CREATE TABLE IF NOT EXISTS accounts (
id_account INTEGER PRIMARY KEY,
@ -136,12 +132,22 @@ impl DbAdapter {
)?;
}
if version <= 1 {
if version < 2 {
self.connection
.execute("ALTER TABLE received_notes ADD excluded BOOL", NO_PARAMS)?;
}
update_schema_version(&self.connection, 2)?;
if version < 3 {
self.connection.execute(
"CREATE TABLE IF NOT EXISTS contacts (
account INTEGER NOT NULL,
name TEXT NOT NULL,
address TEXT NOT NULL,
PRIMARY KEY (account, name))", NO_PARAMS
)?;
}
update_schema_version(&self.connection, 3)?;
Ok(())
}
@ -300,15 +306,9 @@ impl DbAdapter {
}
pub fn store_tx_metadata(&self, id_tx: u32, tx_info: &TransactionInfo) -> anyhow::Result<()> {
let memo = match &tx_info.memo {
Memo::Empty => "".to_string(),
Memo::Text(text) => text.to_string(),
Memo::Future(_) => "Unrecognized".to_string(),
Memo::Arbitrary(_) => "Unrecognized".to_string(),
};
self.connection.execute(
"UPDATE transactions SET address = ?1, memo = ?2 WHERE id_tx = ?3",
params![tx_info.address, &memo, id_tx],
params![tx_info.address, &tx_info.memo, id_tx],
)?;
Ok(())
}
@ -536,6 +536,12 @@ impl DbAdapter {
Ok(())
}
pub fn store_contact(&self, account: u32, contact: &Contact) -> anyhow::Result<()> {
self.connection.execute("INSERT INTO contacts(account, name, address)
VALUES (?1, ?2, ?3) ON CONFLICT DO NOTHING", params![account, &contact.name, &contact.address])?;
Ok(())
}
pub fn get_backup(
&self,
account: u32,

View File

@ -3,7 +3,7 @@ use rand::rngs::OsRng;
use rand::{thread_rng, RngCore};
use rusqlite::NO_PARAMS;
use sync::{
is_valid_key, pedersen_hash, print_witness2, ChainError, DbAdapter, Wallet, Witness, LWD_URL,
pedersen_hash, print_witness2, ChainError, DbAdapter, Wallet, Witness, LWD_URL,
};
use zcash_client_backend::data_api::wallet::ANCHOR_OFFSET;
use zcash_primitives::merkle_tree::Hashable;

View File

@ -110,7 +110,7 @@ pub async fn sync_async(
.collect();
let decrypter = DecryptNode::new(fvks);
let (downloader_tx, mut download_rx) = mpsc::channel::<Range<u32>>(2);
let (downloader_tx, mut download_rx) = mpsc::channel::<Range<u32>>(1);
let (processor_tx, mut processor_rx) = mpsc::channel::<Blocks>(1);
let ld_url2 = ld_url.clone();

View File

@ -16,11 +16,17 @@ use zcash_primitives::transaction::Transaction;
#[derive(Debug)]
pub struct TransactionInfo {
pub address: String,
pub memo: Memo,
pub memo: String,
amount: i64,
pub fee: u64,
}
#[derive(Debug)]
pub struct Contact {
pub name: String,
pub address: String,
}
pub async fn decode_transaction(
client: &mut CompactTxStreamerClient<Channel>,
nfs: &HashMap<(u32, Vec<u8>), u64>,
@ -76,7 +82,7 @@ pub async fn decode_transaction(
tx_memo = memo;
}
} else if let Some((_note, pa, memo)) =
try_sapling_output_recovery(&NETWORK, height, &ovk, &output)
try_sapling_output_recovery(&NETWORK, height, &ovk, &output)
{
address = encode_payment_address(NETWORK.hrp_sapling_payment_address(), &pa);
tx_memo = memo;
@ -85,9 +91,15 @@ pub async fn decode_transaction(
let fee = u64::from(tx.value_balance);
let memo = match Memo::try_from(tx_memo)? {
Memo::Empty => "".to_string(),
Memo::Text(text) => text.to_string(),
Memo::Future(_) => "Unrecognized".to_string(),
Memo::Arbitrary(_) => "Unrecognized".to_string(),
};
let tx_info = TransactionInfo {
address,
memo: Memo::try_from(tx_memo)?,
memo,
amount,
fee,
};
@ -112,12 +124,28 @@ pub async fn retrieve_tx_info(tx_ids: &[u32], ld_url: &str, db_path: &str) -> an
let fvk = db.get_ivk(account)?;
let tx_info =
decode_transaction(&mut client, &nf_map, account, &fvk, &tx_hash, height).await?;
if !tx_info.address.is_empty() && !tx_info.memo.is_empty() {
if let Some(contact) = decode_contact(&tx_info.address, &tx_info.memo)? {
db.store_contact(account, &contact)?;
}
}
db.store_tx_metadata(id_tx, &tx_info)?;
}
Ok(())
}
fn decode_contact(address: &str, memo: &str) -> anyhow::Result<Option<Contact>> {
let res = if let Some(memo_line) = memo.lines().next() {
let name = memo_line.strip_prefix("Contact: ");
name.map(|name| Contact {
name: name.to_string(),
address: address.to_string(),
})
} else { None };
Ok(res)
}
#[cfg(test)]
mod tests {
use crate::transaction::decode_transaction;