Update librustzcash

This commit is contained in:
Hanh 2022-03-15 10:40:08 +08:00
parent f8f9a2bf29
commit f6d35b4d41
9 changed files with 76 additions and 55 deletions

View File

@ -43,10 +43,10 @@ rayon = "1.5.1"
tiny-bip39 = "0.8"
rand = "0.8.4"
rusqlite = { version = "^0.24", features = ["bundled"] }
jubjub = "^0.6"
bls12_381 = "^0.4.0"
ff = "^0.9"
group = "0.9.0"
jubjub = "0.8.0"
bls12_381 = "0.6"
ff = "0.11"
group = "0.11"
byteorder = "^1.4"
secp256k1 = "0.20.2"
tiny-hderive = "0.3.0"
@ -69,23 +69,31 @@ base64 = "^0.13"
[dependencies.zcash_client_backend]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "71b6227a4d96faab2c838159f54b69e6ab034147"
rev = "a25bb7aaa9bf35669280a2c1b7d6fb8b52f30b2d"
[dependencies.zcash_primitives]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "71b6227a4d96faab2c838159f54b69e6ab034147"
rev = "a25bb7aaa9bf35669280a2c1b7d6fb8b52f30b2d"
features = [ "transparent-inputs" ]
[dependencies.zcash_proofs]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "71b6227a4d96faab2c838159f54b69e6ab034147"
rev = "a25bb7aaa9bf35669280a2c1b7d6fb8b52f30b2d"
[dependencies.zcash_params]
path = "../zcash-params"
[dependencies.zcash_address]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "19a97f16945c68c33aedcc89f2a4f4d398658b05"
rev = "a25bb7aaa9bf35669280a2c1b7d6fb8b52f30b2d"
[dependencies.zcash_encoding]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "a25bb7aaa9bf35669280a2c1b7d6fb8b52f30b2d"
[dependencies.zcash_note_encryption]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "a25bb7aaa9bf35669280a2c1b7d6fb8b52f30b2d"
[build-dependencies]
tonic-build = "0.4.2"

View File

@ -4,7 +4,6 @@ use crate::lw_rpc::compact_tx_streamer_client::CompactTxStreamerClient;
use crate::lw_rpc::*;
use crate::advance_tree;
use ff::PrimeField;
use group::GroupEncoding;
use log::info;
use rayon::prelude::*;
use std::collections::HashMap;
@ -18,6 +17,7 @@ use zcash_primitives::sapling::note_encryption::try_sapling_compact_note_decrypt
use zcash_primitives::sapling::{Node, Note, PaymentAddress};
use zcash_primitives::transaction::components::sapling::CompactOutputDescription;
use zcash_primitives::zip32::ExtendedFullViewingKey;
use zcash_note_encryption::EphemeralKeyBytes;
const MAX_CHUNK: u32 = 50000;
@ -119,11 +119,13 @@ pub fn to_output_description(co: &CompactOutput) -> CompactOutputDescription {
let cmu = bls12_381::Scalar::from_repr(cmu).unwrap();
let mut epk = [0u8; 32];
epk.copy_from_slice(&co.epk);
let epk = jubjub::ExtendedPoint::from_bytes(&epk).unwrap();
// let epk = jubjub::ExtendedPoint::from_bytes(&epk).unwrap();
let mut enc_ciphertext = [0u8; 52];
enc_ciphertext.copy_from_slice(&co.ciphertext);
let od = CompactOutputDescription {
epk,
ephemeral_key: EphemeralKeyBytes::from(epk),
cmu,
enc_ciphertext: co.ciphertext.to_vec(),
enc_ciphertext,
};
od
}
@ -144,6 +146,11 @@ fn decrypt_notes<'a, N: Parameters>(
spends.push(Nf(nf));
}
// let _epks: Vec<_> = vtx.outputs.iter().map(|o| {
// &o.epk
// }).collect();
for (output_index, co) in vtx.outputs.iter().enumerate() {
let od = to_output_description(co);
for (&account, vk) in vks.iter() {

View File

@ -3,7 +3,7 @@ use byteorder::WriteBytesExt;
use std::io::{Read, Write};
use zcash_primitives::merkle_tree::{CommitmentTree, Hashable};
use zcash_primitives::sapling::Node;
use zcash_primitives::serialize::{Optional, Vector};
use zcash_encoding::{Optional, Vector};
/*
Same behavior and structure as CommitmentTree<Node> from librustzcash
@ -139,10 +139,10 @@ impl CTree {
}
pub fn write<W: Write>(&self, mut writer: W) -> std::io::Result<()> {
Optional::write(&mut writer, &self.left, |w, n| n.write(w))?;
Optional::write(&mut writer, &self.right, |w, n| n.write(w))?;
Optional::write(&mut writer, self.left, |w, n| n.write(w))?;
Optional::write(&mut writer, self.right, |w, n| n.write(w))?;
Vector::write(&mut writer, &self.parents, |w, e| {
Optional::write(w, e, |w, n| n.write(w))
Optional::write(w, *e, |w, n| n.write(w))
})
}

View File

@ -90,7 +90,7 @@ impl KeyHelpers {
pub fn derive_address(&self, fvk: &ExtendedFullViewingKey) -> anyhow::Result<String> {
let network = self.chain().network();
let (_, payment_address) = fvk.default_address().unwrap();
let (_, payment_address) = fvk.default_address();
let address = encode_payment_address(network.hrp_sapling_payment_address(), &payment_address);
Ok(address)
}

View File

@ -6,7 +6,6 @@ use rusqlite::NO_PARAMS;
use sync::{
pedersen_hash, print_witness2, ChainError, DbAdapter, RecipientMemo, Wallet, Witness, LWD_URL,
};
use zcash_client_backend::data_api::wallet::ANCHOR_OFFSET;
use zcash_primitives::memo::Memo;
use zcash_primitives::merkle_tree::Hashable;
use zcash_primitives::sapling::Node;
@ -38,7 +37,7 @@ async fn test() -> anyhow::Result<()> {
// wallet.new_account_with_key("test", &seed2).unwrap();
// wallet.new_account_with_key("zecpages", &ivk).unwrap();
let res = wallet.sync(true, ANCHOR_OFFSET, progress).await;
let res = wallet.sync(true, 10, progress).await;
if let Err(err) = res {
if let Some(_) = err.downcast_ref::<ChainError>() {
println!("REORG");
@ -98,7 +97,7 @@ async fn test_sync() {
let mut wallet = Wallet::new(CoinType::Zcash, DB_NAME);
wallet.set_lwd_url(LWD_URL).unwrap();
wallet.sync(true, ANCHOR_OFFSET, progress).await.unwrap();
wallet.sync(true, 10, progress).await.unwrap();
}
#[allow(dead_code)]

View File

@ -1,7 +1,7 @@
use crate::db::SpendableNote;
use crate::wallet::RecipientMemo;
use crate::{
connect_lightwalletd, get_branch, get_latest_height, hex_to_hash, GetAddressUtxosReply,
connect_lightwalletd, get_latest_height, hex_to_hash, GetAddressUtxosReply,
RawTransaction
};
use jubjub::Fr;
@ -10,6 +10,7 @@ use rand::rngs::OsRng;
use secp256k1::SecretKey;
use serde::{Deserialize, Serialize};
use std::sync::mpsc;
use anyhow::anyhow;
use tonic::Request;
use zcash_client_backend::address::RecipientAddress;
use zcash_client_backend::encoding::{
@ -20,7 +21,7 @@ use zcash_primitives::consensus::{BlockHeight, Parameters};
use zcash_primitives::legacy::Script;
use zcash_primitives::memo::{Memo, MemoBytes};
use zcash_primitives::merkle_tree::IncrementalWitness;
use zcash_primitives::sapling::keys::OutgoingViewingKey;
use zcash_primitives::keys::OutgoingViewingKey;
use zcash_primitives::sapling::prover::TxProver;
use zcash_primitives::sapling::{Diversifier, Node, PaymentAddress, Rseed};
use zcash_primitives::transaction::builder::{Builder, Progress};
@ -187,10 +188,10 @@ impl TxBuilder {
t_amount += Amount::from_i64(utxo.value_zat).unwrap();
}
}
let target_amount_with_fee = target_amount + DEFAULT_FEE;
let target_amount_with_fee = (target_amount + DEFAULT_FEE).ok_or(anyhow!("Invalid amount"))?;
if target_amount_with_fee > t_amount {
// We need to use some shielded notes because the transparent balance is not enough
let mut amount = target_amount_with_fee - t_amount;
let mut amount = (target_amount_with_fee - t_amount).unwrap();
// Pick spendable notes until we exceed the target_amount_with_fee or we ran out of notes
let mut notes = notes.to_vec();
@ -242,7 +243,7 @@ impl TxBuilder {
recipients: &[RecipientMemo],
) -> anyhow::Result<()> {
let ovk = &fvk.fvk.ovk;
let (_, change) = fvk.default_address().unwrap();
let (_, change) = fvk.default_address();
self.set_change(&ovk, &change)?;
for r in recipients.iter() {
@ -291,7 +292,7 @@ impl Tx {
&self,
tsk: Option<SecretKey>,
zsk: &ExtendedSpendingKey,
prover: &impl TxProver<OsRng>,
prover: &impl TxProver,
progress_callback: impl Fn(Progress) + Send + 'static,
) -> anyhow::Result<Vec<u8>> {
let chain = get_coin_chain(self.coin_type);
@ -361,7 +362,7 @@ impl Tx {
let m = hex::decode(&txout.memo)?;
memo[..m.len()].copy_from_slice(&m);
let memo = MemoBytes::from_bytes(&memo)?;
builder.add_sapling_output(Some(ovk), pa, amount, Some(memo))?;
builder.add_sapling_output(Some(ovk), pa, amount, memo)?;
}
}
}
@ -375,8 +376,7 @@ impl Tx {
progress_callback(progress);
}
});
let consensus_branch_id = get_branch(chain.network(), u32::from(last_height));
let (tx, _) = builder.build(consensus_branch_id, prover)?;
let (tx, _) = builder.build(prover)?;
let mut raw_tx = vec![];
tx.write(&mut raw_tx)?;

View File

@ -5,6 +5,7 @@ use std::collections::HashMap;
use std::convert::TryFrom;
use std::sync::mpsc;
use std::sync::mpsc::SyncSender;
use anyhow::anyhow;
use tonic::transport::Channel;
use tonic::Request;
use zcash_client_backend::encoding::{
@ -17,7 +18,7 @@ use zcash_primitives::sapling::note_encryption::{
};
use zcash_primitives::transaction::Transaction;
use zcash_primitives::zip32::ExtendedFullViewingKey;
use zcash_params::coin::{CoinType, get_coin_chain};
use zcash_params::coin::{CoinType, get_coin_chain, get_branch};
#[derive(Debug)]
pub struct TransactionInfo {
@ -28,7 +29,7 @@ pub struct TransactionInfo {
pub address: String,
pub memo: String,
pub amount: i64,
pub fee: u64,
// pub fee: u64,
pub contacts: Vec<Contact>,
}
@ -50,6 +51,7 @@ pub async fn decode_transaction(
height: u32,
index: u32,
) -> anyhow::Result<TransactionInfo> {
let consensus_branch_id = get_branch(network, u32::from(height));
let ivk = fvk.fvk.vk.ivk();
let ovk = fvk.fvk.ovk;
@ -62,24 +64,27 @@ pub async fn decode_transaction(
.get_transaction(Request::new(tx_filter))
.await?
.into_inner();
let tx = Transaction::read(&*raw_tx.data)?;
let tx = Transaction::read(&*raw_tx.data, consensus_branch_id)?;
let height = BlockHeight::from_u32(height);
let mut amount = 0i64;
let mut taddress = String::new();
let mut zaddress = String::new();
for spend in tx.shielded_spends.iter() {
let tx = tx.into_data();
let sapling_bundle = tx.sapling_bundle().ok_or(anyhow!("No sapling bundle"))?;
for spend in sapling_bundle.shielded_spends.iter() {
let nf = spend.nullifier.to_vec();
if let Some(&v) = nfs.get(&(account, nf)) {
amount -= v as i64;
}
}
let mut contact_decoder = ContactDecoder::new(tx.shielded_outputs.len());
let mut contact_decoder = ContactDecoder::new(tx.sapling_bundle().unwrap().shielded_outputs.len());
let mut tx_memo: Memo = Memo::Empty;
for output in tx.vout.iter() {
for output in tx.transparent_bundle().ok_or(anyhow!("No transparent bundle"))?.vout.iter() {
if let Some(taddr) = output.script_pubkey.address() {
taddress = encode_transparent_address(
&network.b58_pubkey_address_prefix(),
@ -89,7 +94,7 @@ pub async fn decode_transaction(
}
}
for output in tx.shielded_outputs.iter() {
for output in sapling_bundle.shielded_outputs.iter() {
if let Some((note, pa, memo)) = try_sapling_note_decryption(network, height, &ivk, output)
{
amount += note.value as i64; // change or self transfer
@ -112,7 +117,9 @@ pub async fn decode_transaction(
}
}
let fee = u64::from(tx.value_balance);
// let fee =
// u64::from() +
// u64::from(tx.sapling_bundle().unwrap().value_balance);
// zaddress must be one of ours
// taddress is not always ours
@ -135,7 +142,7 @@ pub async fn decode_transaction(
address,
memo,
amount,
fee,
// fee,
contacts,
};

View File

@ -1,5 +1,4 @@
use std::convert::TryFrom;
use zcash_address::unified::{Address, Receiver};
use zcash_address::unified::{Address, Container, Receiver};
use zcash_address::{FromAddress, Network, ToAddress, UnsupportedAddress, ZcashAddress};
#[derive(Debug, Clone)]
@ -17,7 +16,7 @@ impl FromAddress for MyReceiver {
}
fn from_unified(net: Network, data: Address) -> Result<Self, UnsupportedAddress> {
for r in data.receivers().iter() {
for r in data.items_as_parsed().iter() {
match r {
Receiver::Sapling(data) => {
return Ok(MyReceiver {
@ -39,18 +38,19 @@ impl FromAddress for MyReceiver {
}
}
pub fn get_ua(sapling_addr: &str, transparent_addr: &str) -> anyhow::Result<ZcashAddress> {
let sapling_addr = ZcashAddress::try_from_encoded(sapling_addr)?;
let transparent_addr = ZcashAddress::try_from_encoded(transparent_addr)?;
let receivers: Vec<_> = vec![sapling_addr, transparent_addr]
.iter()
.map(|r| r.clone().convert::<MyReceiver>().unwrap())
.collect();
let net = receivers.first().unwrap().net.clone();
let receivers: Vec<_> = receivers.iter().map(|r| r.receiver.clone()).collect();
let ua: Address = Address::try_from(receivers)?;
let ua_address = ZcashAddress::from_unified(net, ua);
Ok(ua_address)
pub fn get_ua(_sapling_addr: &str, _transparent_addr: &str) -> anyhow::Result<ZcashAddress> {
todo!()
// let sapling_addr = ZcashAddress::try_from_encoded(sapling_addr)?;
// let transparent_addr = ZcashAddress::try_from_encoded(transparent_addr)?;
// let receivers: Vec<_> = vec![sapling_addr, transparent_addr]
// .iter()
// .map(|r| r.clone().convert::<MyReceiver>().unwrap())
// .collect();
// let net = receivers.first().unwrap().net.clone();
// let receivers: Vec<_> = receivers.iter().map(|r| r.receiver.clone()).collect();
// let ua: Address = Address::from_inner(receivers)?;
// let ua_address = ZcashAddress::from_unified(net, ua);
// Ok(ua_address)
}
pub fn get_sapling(ua_addr: &str) -> anyhow::Result<ZcashAddress> {

View File

@ -399,8 +399,8 @@ impl Wallet {
let mut diversifier_index = self.db.get_diversifier(account)?;
diversifier_index.increment().unwrap();
let (new_diversifier_index, pa) = fvk
.address(diversifier_index)
.map_err(|_| anyhow::anyhow!("Cannot generate new address"))?;
.find_address(diversifier_index)
.ok_or_else(|| anyhow::anyhow!("Cannot generate new address"))?;
self.db.store_diversifier(account, &new_diversifier_index)?;
let pa = encode_payment_address(self.network().hrp_sapling_payment_address(), &pa);
Ok(pa)