Contacts
This commit is contained in:
parent
ac0673aabd
commit
653cc44a49
36
src/db.rs
36
src/db.rs
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue