Skip to content

Commit

Permalink
Merge pull request #2 from ChainSafe/willem/get_transparent_balances
Browse files Browse the repository at this point in the history
Add new fields to memWallet and an implementation of get_transparent_balance
  • Loading branch information
willemolding authored Aug 21, 2024
2 parents 34508f2 + e8329f4 commit 8a46ea9
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 18 deletions.
59 changes: 59 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,62 @@ root = true

[*.md]
indent_style = space
[*]
cpp_indent_braces=false
cpp_indent_multi_line_relative_to=innermost_parenthesis
cpp_indent_within_parentheses=indent
cpp_indent_preserve_within_parentheses=false
cpp_indent_case_labels=false
cpp_indent_case_contents=true
cpp_indent_case_contents_when_block=false
cpp_indent_lambda_braces_when_parameter=true
cpp_indent_goto_labels=one_left
cpp_indent_preprocessor=leftmost_column
cpp_indent_access_specifiers=false
cpp_indent_namespace_contents=true
cpp_indent_preserve_comments=false
cpp_new_line_before_open_brace_namespace=ignore
cpp_new_line_before_open_brace_type=ignore
cpp_new_line_before_open_brace_function=ignore
cpp_new_line_before_open_brace_block=ignore
cpp_new_line_before_open_brace_lambda=ignore
cpp_new_line_scope_braces_on_separate_lines=false
cpp_new_line_close_brace_same_line_empty_type=false
cpp_new_line_close_brace_same_line_empty_function=false
cpp_new_line_before_catch=true
cpp_new_line_before_else=true
cpp_new_line_before_while_in_do_while=false
cpp_space_before_function_open_parenthesis=remove
cpp_space_within_parameter_list_parentheses=false
cpp_space_between_empty_parameter_list_parentheses=false
cpp_space_after_keywords_in_control_flow_statements=true
cpp_space_within_control_flow_statement_parentheses=false
cpp_space_before_lambda_open_parenthesis=false
cpp_space_within_cast_parentheses=false
cpp_space_after_cast_close_parenthesis=false
cpp_space_within_expression_parentheses=false
cpp_space_before_block_open_brace=true
cpp_space_between_empty_braces=false
cpp_space_before_initializer_list_open_brace=false
cpp_space_within_initializer_list_braces=true
cpp_space_preserve_in_initializer_list=true
cpp_space_before_open_square_bracket=false
cpp_space_within_square_brackets=false
cpp_space_before_empty_square_brackets=false
cpp_space_between_empty_square_brackets=false
cpp_space_group_square_brackets=true
cpp_space_within_lambda_brackets=false
cpp_space_between_empty_lambda_brackets=false
cpp_space_before_comma=false
cpp_space_after_comma=true
cpp_space_remove_around_member_operators=true
cpp_space_before_inheritance_colon=true
cpp_space_before_constructor_colon=true
cpp_space_remove_before_semicolon=true
cpp_space_after_semicolon=false
cpp_space_remove_around_unary_operator=true
cpp_space_around_binary_operator=insert
cpp_space_around_assignment_operator=insert
cpp_space_pointer_reference_alignment=left
cpp_space_around_ternary_operator=insert
cpp_wrap_preserve_blocks=one_liners
1 change: 0 additions & 1 deletion zcash_client_memory/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use zcash_protocol::memo;

use crate::mem_wallet::AccountId;


type Type = AddressGenerationError;

#[derive(Debug, thiserror::Error)]
Expand Down
19 changes: 18 additions & 1 deletion zcash_client_memory/src/mem_wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use zip32::{fingerprint::SeedFingerprint, DiversifierIndex, Scope};
use zcash_primitives::{
block::BlockHash,
consensus::{BlockHeight, Network},
transaction::{Transaction, TxId},
transaction::{components::OutPoint, Transaction, TxId},
};
use zcash_protocol::{
memo::{self, Memo, MemoBytes},
Expand Down Expand Up @@ -90,6 +90,14 @@ pub struct MemoryWalletDb {
accounts: Vec<Account>,
blocks: BTreeMap<BlockHeight, MemoryWalletBlock>,
tx_idx: HashMap<TxId, BlockHeight>,

/// Tracks transparent outputs received by this wallet indexed by their OutPoint which defines the
/// transaction and index where the output was created
transparent_received_outputs: HashMap<OutPoint, TransparentReceivedOutput>,

/// Tracks spends of received outputs. In thix case the TxId is the spending transaction
/// from this wallet.
transparent_received_output_spends: HashMap<OutPoint, TxId>,
sapling_spends: BTreeMap<sapling::Nullifier, (TxId, bool)>,
#[cfg(feature = "orchard")]
orchard_spends: BTreeMap<orchard::note::Nullifier, (TxId, bool)>,
Expand All @@ -113,6 +121,8 @@ impl MemoryWalletDb {
accounts: Vec::new(),
blocks: BTreeMap::new(),
tx_idx: HashMap::new(),
transparent_received_outputs: HashMap::new(),
transparent_received_output_spends: HashMap::new(),
sapling_spends: BTreeMap::new(),
#[cfg(feature = "orchard")]
orchard_spends: BTreeMap::new(),
Expand Down Expand Up @@ -231,3 +241,10 @@ impl ViewingKey {
}
}
}

#[derive(Debug, Clone)]
struct TransparentReceivedOutput {
output: WalletTransparentOutput,
account_id: AccountId,
tx_id: TxId,
}
61 changes: 47 additions & 14 deletions zcash_client_memory/src/mem_wallet/wallet_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ use std::{
use zcash_keys::keys::{AddressGenerationError, DerivationError, UnifiedIncomingViewingKey};
use zip32::{fingerprint::SeedFingerprint, DiversifierIndex, Scope};

use std::ops::Add;
use zcash_client_backend::{
address::UnifiedAddress,
data_api::{
chain::ChainState, Account as _, AccountPurpose, AccountSource, SeedRelevance,
TransactionDataRequest, TransactionStatus,
},
keys::{UnifiedAddressRequest, UnifiedFullViewingKey, UnifiedSpendingKey},
wallet::{NoteId, WalletSpend, WalletTransparentOutput, WalletTx},
};
use zcash_primitives::{
block::BlockHash,
consensus::{BlockHeight, Network},
Expand All @@ -23,29 +33,20 @@ use zcash_protocol::{
ShieldedProtocol::{Orchard, Sapling},
};

use zcash_client_backend::{
address::UnifiedAddress,
data_api::{
chain::ChainState, Account as _, AccountPurpose, AccountSource, SeedRelevance,
TransactionDataRequest, TransactionStatus,
},
keys::{UnifiedAddressRequest, UnifiedFullViewingKey, UnifiedSpendingKey},
wallet::{NoteId, WalletSpend, WalletTransparentOutput, WalletTx},
};

use zcash_client_backend::data_api::{
chain::CommitmentTreeRoot, scanning::ScanRange, AccountBirthday, BlockMetadata,
DecryptedTransaction, NullifierQuery, ScannedBlock, SentTransaction, WalletCommitmentTrees,
WalletRead, WalletSummary, WalletWrite, SAPLING_SHARD_HEIGHT,
};
use zcash_primitives::transaction::components::OutPoint;

#[cfg(feature = "transparent-inputs")]
use {
zcash_client_backend::wallet::TransparentAddressMetadata,
zcash_primitives::legacy::TransparentAddress,
};

use super::{Account, AccountId, MemoryWalletDb};
use super::{Account, AccountId, MemoryWalletDb, TransparentReceivedOutput};
use crate::error::Error;

impl WalletRead for MemoryWalletDb {
Expand Down Expand Up @@ -234,10 +235,42 @@ impl WalletRead for MemoryWalletDb {
#[cfg(feature = "transparent-inputs")]
fn get_transparent_balances(
&self,
_account: Self::AccountId,
_max_height: BlockHeight,
account: Self::AccountId,
max_height: BlockHeight,
) -> Result<HashMap<TransparentAddress, Zatoshis>, Self::Error> {
Ok(HashMap::new())
// scan all transparent outputs and return those in a tx belonging to this account
// as a map between the address and the total value received
Ok(self
.transparent_received_outputs
.iter()
.filter(|(_, output)| output.account_id == account) // that belong to this account
.filter(|(outpoint, output)| {
// where the tx creating the output is mined
if let Some(height) = self.tx_idx.get(&output.tx_id) {
height <= &max_height
} else {
false
}
})
.filter(|(outpoint, _)| {
// that are unspent
!self
.transparent_received_output_spends
.contains_key(&outpoint)

Check failure on line 259 in zcash_client_memory/src/mem_wallet/wallet_read.rs

View workflow job for this annotation

GitHub Actions / Clippy (MSRV)

this expression creates a reference which is immediately dereferenced by the compiler

error: this expression creates a reference which is immediately dereferenced by the compiler --> zcash_client_memory/src/mem_wallet/wallet_read.rs:259:35 | 259 | .contains_key(&outpoint) | ^^^^^^^^^ help: change this to: `outpoint` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow = note: `-D clippy::needless-borrow` implied by `-D warnings`
})
.fold(
HashMap::new(),
|mut res, (_, TransparentReceivedOutput { output, .. })| {
let addr = output.recipient_address().clone();

Check failure on line 264 in zcash_client_memory/src/mem_wallet/wallet_read.rs

View workflow job for this annotation

GitHub Actions / Clippy (MSRV)

using `clone` on type `TransparentAddress` which implements the `Copy` trait

error: using `clone` on type `TransparentAddress` which implements the `Copy` trait --> zcash_client_memory/src/mem_wallet/wallet_read.rs:264:32 | 264 | let addr = output.recipient_address().clone(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try dereferencing it: `*output.recipient_address()` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_copy = note: `-D clippy::clone-on-copy` implied by `-D warnings`
let zats = res
.get(&addr)
.unwrap_or(&Zatoshis::ZERO)
.add(output.value())
.expect("Can always add a non-negative value to zero");
res.insert(addr, zats);
res
},
))
}

fn transaction_data_requests(&self) -> Result<Vec<TransactionDataRequest>, Self::Error> {
Expand Down
3 changes: 2 additions & 1 deletion zcash_client_memory/src/mem_wallet/wallet_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ impl WalletWrite for MemoryWalletDb {
.transpose()?
.unwrap_or(zip32::AccountId::ZERO);

let usk = UnifiedSpendingKey::from_seed(&self.network, seed.expose_secret(), account_index)?;
let usk =
UnifiedSpendingKey::from_seed(&self.network, seed.expose_secret(), account_index)?;
let ufvk = usk.to_unified_full_viewing_key();
let account = Account {
account_id: AccountId(self.accounts.len() as u32),
Expand Down
2 changes: 1 addition & 1 deletion zcash_primitives/src/transaction/components/transparent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl<A: Authorization> Bundle<A> {
}
}

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct OutPoint {
hash: TxId,
n: u32,
Expand Down

0 comments on commit 8a46ea9

Please sign in to comment.