Update librustzcash
This commit is contained in:
parent
f8f9a2bf29
commit
f6d35b4d41
24
Cargo.toml
24
Cargo.toml
|
@ -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"
|
||||
|
|
15
src/chain.rs
15
src/chain.rs
|
@ -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() {
|
||||
|
|
|
@ -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))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)]
|
||||
|
|
18
src/pay.rs
18
src/pay.rs
|
@ -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)?;
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
30
src/ua.rs
30
src/ua.rs
|
@ -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> {
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue