Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make types explicit in the transaction_record scope #968

Merged
merged 2 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 3 additions & 14 deletions zingolib/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
//! TODO: Add Mod Description Here

use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use zcash_primitives::memo::Memo;

use json::JsonValue;
use log::{info, warn};
use orchard::keys::SpendingKey as OrchardSpendingKey;
use orchard::note_encryption::OrchardDomain;
use orchard::tree::MerkleHashOrchard;
use rand::rngs::OsRng;
use rand::Rng;
use sapling_crypto::note_encryption::SaplingDomain;

use sapling_crypto::zip32::DiversifiableFullViewingKey;

Expand All @@ -25,19 +23,10 @@ use tokio::sync::RwLock;
use zcash_primitives::zip339::Mnemonic;

use zcash_client_backend::proto::service::TreeState;
use zcash_encoding::{Optional, Vector};
use zcash_note_encryption::Domain;

use zcash_primitives::{consensus::BlockHeight, memo::Memo};

use zingo_status::confirmation_status::ConfirmationStatus;
use zcash_encoding::Optional;
use zingoconfig::ZingoConfig;

use crate::wallet::notes::ShieldedNoteInterface;

use crate::wallet::traits::ReadableWriteable;

use self::data::{WitnessTrees, COMMITMENT_TREE_LEVELS};
use self::data::WitnessTrees;
use self::keys::unified::Fvk as _;
use self::keys::unified::WalletCapability;

Expand Down
88 changes: 54 additions & 34 deletions zingolib/src/wallet/transaction_record.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
//! TODO: Add Mod Description Here!
use crate::wallet::notes::interface::ShieldedNoteInterface as _;
use std::io::{self, Read, Write};

use byteorder::{LittleEndian, ReadBytesExt as _, WriteBytesExt as _};
use incrementalmerkletree::witness::IncrementalWitness;
use zcash_primitives::transaction::TxId;
use orchard::tree::MerkleHashOrchard;
use zcash_primitives::{consensus::BlockHeight, transaction::TxId};

use crate::error::ZingoLibError;
use crate::wallet::notes;

use super::{
data::{OutgoingTxData, PoolNullifier},
traits::DomainWalletExt,
*,
data::{OutgoingTxData, PoolNullifier, COMMITMENT_TREE_LEVELS},
keys::unified::WalletCapability,
traits::{DomainWalletExt, ReadableWriteable as _},
};

/// Everything (SOMETHING) about a transaction
#[derive(Debug)]
pub struct TransactionRecord {
/// the relationship of the transaction to the blockchain. can be either Broadcast (to mempool}, or Confirmed.
pub status: ConfirmationStatus,
pub status: zingo_status::confirmation_status::ConfirmationStatus,

/// Timestamp of Tx. Added in v4
pub datetime: u64,
Expand Down Expand Up @@ -58,7 +63,11 @@ pub struct TransactionRecord {
// set
impl TransactionRecord {
/// TODO: Add Doc Comment Here!
pub fn new(status: ConfirmationStatus, datetime: u64, transaction_id: &TxId) -> Self {
pub fn new(
status: zingo_status::confirmation_status::ConfirmationStatus,
datetime: u64,
transaction_id: &TxId,
) -> Self {
TransactionRecord {
status,
datetime,
Expand Down Expand Up @@ -126,8 +135,13 @@ impl TransactionRecord {

/// TODO: Add Doc Comment Here!
pub fn is_incoming_transaction(&self) -> bool {
self.sapling_notes.iter().any(|note| !note.is_change())
|| self.orchard_notes.iter().any(|note| !note.is_change())
self.sapling_notes
.iter()
.any(|note| !notes::ShieldedNoteInterface::is_change(note))
|| self
.orchard_notes
.iter()
.any(|note| !notes::ShieldedNoteInterface::is_change(note))
|| !self.transparent_notes.is_empty()
}

Expand All @@ -140,17 +154,17 @@ impl TransactionRecord {
/// TODO: Add Doc Comment Here!
fn pool_change_returned<D: DomainWalletExt>(&self) -> u64
where
<D as Domain>::Note: PartialEq + Clone,
<D as Domain>::Recipient: traits::Recipient,
<D as zcash_note_encryption::Domain>::Note: PartialEq + Clone,
<D as zcash_note_encryption::Domain>::Recipient: super::traits::Recipient,
{
D::sum_pool_change(self)
}

/// TODO: Add Doc Comment Here!
pub fn pool_value_received<D: DomainWalletExt>(&self) -> u64
where
<D as Domain>::Note: PartialEq + Clone,
<D as Domain>::Recipient: traits::Recipient,
<D as zcash_note_encryption::Domain>::Note: PartialEq + Clone,
<D as zcash_note_encryption::Domain>::Recipient: super::traits::Recipient,
{
D::to_notes_vec(self)
.iter()
Expand All @@ -160,13 +174,14 @@ impl TransactionRecord {

/// TODO: Add Doc Comment Here!
pub fn total_change_returned(&self) -> u64 {
self.pool_change_returned::<SaplingDomain>() + self.pool_change_returned::<OrchardDomain>()
self.pool_change_returned::<sapling_crypto::note_encryption::SaplingDomain>()
+ self.pool_change_returned::<orchard::note_encryption::OrchardDomain>()
}

/// TODO: Add Doc Comment Here!
pub fn total_value_received(&self) -> u64 {
self.pool_value_received::<OrchardDomain>()
+ self.pool_value_received::<SaplingDomain>()
self.pool_value_received::<orchard::note_encryption::OrchardDomain>()
+ self.pool_value_received::<sapling_crypto::note_encryption::SaplingDomain>()
+ self
.transparent_notes
.iter()
Expand Down Expand Up @@ -236,17 +251,17 @@ impl TransactionRecord {

let transaction_id = TxId::from_bytes(transaction_id_bytes);

let sapling_notes = Vector::read_collected_mut(&mut reader, |r| {
let sapling_notes = zcash_encoding::Vector::read_collected_mut(&mut reader, |r| {
notes::SaplingNote::read(r, (wallet_capability, trees.as_mut().map(|t| &mut t.0)))
})?;
let orchard_notes = if version > 22 {
Vector::read_collected_mut(&mut reader, |r| {
zcash_encoding::Vector::read_collected_mut(&mut reader, |r| {
notes::OrchardNote::read(r, (wallet_capability, trees.as_mut().map(|t| &mut t.1)))
})?
} else {
vec![]
};
let utxos = Vector::read(&mut reader, |r| notes::TransparentNote::read(r))?;
let utxos = zcash_encoding::Vector::read(&mut reader, |r| notes::TransparentNote::read(r))?;

let total_sapling_value_spent = reader.read_u64::<LittleEndian>()?;
let total_transparent_value_spent = reader.read_u64::<LittleEndian>()?;
Expand All @@ -257,20 +272,21 @@ impl TransactionRecord {
};

// Outgoing metadata was only added in version 2
let outgoing_metadata = Vector::read(&mut reader, |r| OutgoingTxData::read(r))?;
let outgoing_metadata =
zcash_encoding::Vector::read(&mut reader, |r| OutgoingTxData::read(r))?;

let _full_tx_scanned = reader.read_u8()? > 0;

let zec_price = if version <= 4 {
None
} else {
Optional::read(&mut reader, |r| r.read_f64::<LittleEndian>())?
zcash_encoding::Optional::read(&mut reader, |r| r.read_f64::<LittleEndian>())?
};

let spent_sapling_nullifiers = if version <= 5 {
vec![]
} else {
Vector::read(&mut reader, |r| {
zcash_encoding::Vector::read(&mut reader, |r| {
let mut n = [0u8; 32];
r.read_exact(&mut n)?;
Ok(sapling_crypto::Nullifier(n))
Expand All @@ -280,13 +296,13 @@ impl TransactionRecord {
let spent_orchard_nullifiers = if version <= 21 {
vec![]
} else {
Vector::read(&mut reader, |r| {
zcash_encoding::Vector::read(&mut reader, |r| {
let mut n = [0u8; 32];
r.read_exact(&mut n)?;
Ok(orchard::note::Nullifier::from_bytes(&n).unwrap())
})?
};
let status = ConfirmationStatus::from_blockheight_and_unconfirmed_bool(block, unconfirmed);
let status = zingo_status::confirmation_status::ConfirmationStatus::from_blockheight_and_unconfirmed_bool(block, unconfirmed);
Ok(Self {
status,
datetime,
Expand Down Expand Up @@ -322,27 +338,27 @@ impl TransactionRecord {

writer.write_all(self.txid.as_ref())?;

Vector::write(&mut writer, &self.sapling_notes, |w, nd| nd.write(w))?;
Vector::write(&mut writer, &self.orchard_notes, |w, nd| nd.write(w))?;
Vector::write(&mut writer, &self.transparent_notes, |w, u| u.write(w))?;
zcash_encoding::Vector::write(&mut writer, &self.sapling_notes, |w, nd| nd.write(w))?;
zcash_encoding::Vector::write(&mut writer, &self.orchard_notes, |w, nd| nd.write(w))?;
zcash_encoding::Vector::write(&mut writer, &self.transparent_notes, |w, u| u.write(w))?;

for pool in self.value_spent_by_pool() {
writer.write_u64::<LittleEndian>(pool)?;
}

// Write the outgoing metadata
Vector::write(&mut writer, &self.outgoing_tx_data, |w, om| om.write(w))?;
zcash_encoding::Vector::write(&mut writer, &self.outgoing_tx_data, |w, om| om.write(w))?;

writer.write_u8(0)?;

Optional::write(&mut writer, self.price, |w, p| {
zcash_encoding::Optional::write(&mut writer, self.price, |w, p| {
w.write_f64::<LittleEndian>(p)
})?;

Vector::write(&mut writer, &self.spent_sapling_nullifiers, |w, n| {
zcash_encoding::Vector::write(&mut writer, &self.spent_sapling_nullifiers, |w, n| {
w.write_all(&n.0)
})?;
Vector::write(&mut writer, &self.spent_orchard_nullifiers, |w, n| {
zcash_encoding::Vector::write(&mut writer, &self.spent_orchard_nullifiers, |w, n| {
w.write_all(&n.to_bytes())
})?;

Expand Down Expand Up @@ -416,8 +432,6 @@ mod tests {
use crate::wallet::notes::transparent::mocks::TransparentNoteBuilder;
use crate::wallet::transaction_record::mocks::TransactionRecordBuilder;

use super::*;

#[test]
pub fn blank_record() {
let new = TransactionRecordBuilder::default().build();
Expand All @@ -426,8 +440,14 @@ mod tests {
assert!(!new.is_outgoing_transaction());
assert!(!new.is_incoming_transaction());
// assert_eq!(new.net_spent(), 0);
assert_eq!(new.pool_change_returned::<OrchardDomain>(), 0);
assert_eq!(new.pool_change_returned::<SaplingDomain>(), 0);
assert_eq!(
new.pool_change_returned::<orchard::note_encryption::OrchardDomain>(),
0
);
assert_eq!(
new.pool_change_returned::<sapling_crypto::note_encryption::SaplingDomain>(),
0
);
assert_eq!(new.total_value_received(), 0);
assert_eq!(new.total_value_spent(), 0);
assert_eq!(new.value_outgoing(), 0);
Expand Down
Loading