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

Proper usk update branch #21

Open
wants to merge 25 commits into
base: main_zingolib
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
479098f
removed meta push in create_proposed_transaction
fluidvanadium Apr 7, 2024
4ef584f
change sent to external address
fluidvanadium Apr 7, 2024
c1442fb
removed meta push in create_proposed_transaction
fluidvanadium Apr 7, 2024
b1e70fd
enable build_server
fluidvanadium Apr 7, 2024
bcbae0b
removed store functionality in create_proposed_transaction
fluidvanadium Apr 19, 2024
c9141bd
doc-comment and rename new function
fluidvanadium Apr 19, 2024
1aa9455
Merge pull request #10 from fluidvanadium/avoid_wallet_write
zancas Apr 25, 2024
d876a1c
pub scoped caluculate_proposed_trnsaction
fluidvanadium Apr 29, 2024
4c67b47
Merge pull request #11 from fluidvanadium/pub_calculate
fluidvanadium Apr 29, 2024
84469ad
impl std::fmt::Display for NoteId
fluidvanadium May 1, 2024
239c894
add extra method for non-traditional tkey derevation
AloeareV May 15, 2024
471a062
create 0-value change
fluidvanadium May 30, 2024
c2962db
update changelog
fluidvanadium Jun 17, 2024
b2c17c5
Merge pull request #12 from fluidvanadium/add_changelog
fluidvanadium Jun 17, 2024
527256a
allow override_sapling_change_address so zingo doesnt have to scan so…
fluidvanadium Jun 17, 2024
50ffcd4
no funky extra change output
fluidvanadium Jun 26, 2024
7b12909
Revert "no funky extra change output"
zancas Jun 26, 2024
3ab3029
move the 0-value change case into the dust case
zancas Jun 29, 2024
ae0d477
Merge pull request #18 from zancas/always_require_change_for_memo
zancas Jun 29, 2024
773cf72
Merge remote-tracking branch 'ecc/main' into zupdate
fluidvanadium Jul 10, 2024
7a7a0d6
removed Marked enum
fluidvanadium Jul 10, 2024
f93bfad
data source <- datasource
fluidvanadium Jul 10, 2024
5492cbc
pub kind getter
fluidvanadium Jul 23, 2024
b957e42
removed usk_to_tkey
fluidvanadium Jul 23, 2024
658cf92
pub fn UnifiedSpendingKey::from_checked_parts
fluidvanadium Jul 23, 2024
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion components/zcash_address/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ pub struct ZcashAddress {

/// Known kinds of Zcash addresses.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
enum AddressKind {
pub enum AddressKind {
Sprout([u8; 64]),
Sapling([u8; 43]),
Unified(unified::Address),
Expand Down Expand Up @@ -302,6 +302,10 @@ impl ZcashAddress {
_ => false,
}
}

pub fn kind(&self) -> &AddressKind {
&self.kind
}
}

#[cfg(feature = "test-dependencies")]
Expand Down
8 changes: 7 additions & 1 deletion zcash_client_backend/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this library adheres to Rust's notion of
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [Zingo]
- replace create_proposed_transaction with `calculate_proposed_transaction`
- dont try to write the calculated transaction to wallet, that will be handled later
- ignore collecting any transaction metadata
- handle usk differently
- modify change algorithm
- added display for NoteId

### Added
- `zcash_client_backend::data_api`:
Expand Down
1 change: 1 addition & 0 deletions zcash_client_backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ tonic = { workspace = true, optional = true, features = ["prost", "codegen"] }
# - Secret management
secrecy.workspace = true
subtle.workspace = true
secp256k1.workspace = true

# - Shielded protocols
bls12_381.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion zcash_client_backend/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ fn build() -> io::Result<()> {

// Build the gRPC types and client.
tonic_build::configure()
.build_server(false)
.build_server(true)
.client_mod_attribute(
"cash.z.wallet.sdk.rpc",
r#"#[cfg(feature = "lightwalletd-tonic")]"#,
Expand Down
2 changes: 1 addition & 1 deletion zcash_client_backend/src/data_api/chain/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl<WE: fmt::Display, BE: fmt::Display> fmt::Display for Error<WE, BE> {
Error::Wallet(e) => {
write!(
f,
"The underlying datasource produced the following error: {}",
"The underlying data source produced the following error: {}",
e
)
}
Expand Down
2 changes: 1 addition & 1 deletion zcash_client_backend/src/data_api/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ where
Error::DataSource(e) => {
write!(
f,
"The underlying datasource produced the following error: {}",
"The underlying data source produced the following error: {}",
e
)
}
Expand Down
172 changes: 16 additions & 156 deletions zcash_client_backend/src/data_api/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use crate::{
fees::{self, DustOutputPolicy},
keys::UnifiedSpendingKey,
proposal::{self, Proposal, ProposalError},
wallet::{Note, OvkPolicy, Recipient},
wallet::{Note, OvkPolicy, Recipient, TransparentAddressMetadata},
zip321::{self, Payment},
PoolType, ShieldedProtocol,
};
Expand Down Expand Up @@ -597,9 +597,10 @@ where
ParamsT: consensus::Parameters + Clone,
FeeRuleT: FeeRule,
{
unimplemented!();
let mut step_results = Vec::with_capacity(proposal.steps().len());
for step in proposal.steps() {
let step_result = create_proposed_transaction(
let step_result = calculate_proposed_transaction(
wallet_db,
params,
spend_prover,
Expand All @@ -610,6 +611,7 @@ where
proposal.min_target_height(),
&step_results,
step,
None,
)?;
step_results.push((step, step_result));
}
Expand All @@ -623,9 +625,10 @@ where
.expect("proposal.steps is NonEmpty"))
}

/// Zingo uses calculate_proposed_transaction to create the transaction, and then stores it ASYNCRONOUSLY
#[allow(clippy::too_many_arguments)]
#[allow(clippy::type_complexity)]
fn create_proposed_transaction<DbT, ParamsT, InputsErrT, FeeRuleT, N>(
pub fn calculate_proposed_transaction<DbT, ParamsT, InputsErrT, FeeRuleT, N>(
wallet_db: &mut DbT,
params: &ParamsT,
spend_prover: &impl SpendProver,
Expand All @@ -636,9 +639,10 @@ fn create_proposed_transaction<DbT, ParamsT, InputsErrT, FeeRuleT, N>(
min_target_height: BlockHeight,
prior_step_results: &[(&proposal::Step<N>, BuildResult)],
proposal_step: &proposal::Step<N>,
override_sapling_change_address: Option<sapling::PaymentAddress>,
) -> Result<BuildResult, ErrorT<DbT, InputsErrT, FeeRuleT>>
where
DbT: WalletWrite + WalletCommitmentTrees,
DbT: WalletRead + WalletCommitmentTrees,
ParamsT: consensus::Parameters + Clone,
FeeRuleT: FeeRule,
{
Expand Down Expand Up @@ -806,10 +810,12 @@ where
.clone()
.ok_or_else(|| Error::NoSpendingKey(addr.encode(params)))?;

let secret_key = usk
.transparent()
.derive_secret_key(address_metadata.scope(), address_metadata.address_index())
.unwrap();
let secret_key = usk.transparent()
.derive_secret_key(
address_metadata.scope(),
address_metadata.address_index(),
)
.unwrap();

utxos_spent.push(outpoint.clone());
builder.add_transparent_input(secret_key, outpoint, utxo)?;
Expand Down Expand Up @@ -922,10 +928,6 @@ where
Some(sapling_dfvk.to_ovk(Scope::Internal))
};

#[cfg(feature = "orchard")]
let mut orchard_output_meta = vec![];
let mut sapling_output_meta = vec![];
let mut transparent_output_meta = vec![];
for (payment, output_pool) in proposal_step
.payment_pools()
.iter()
Expand Down Expand Up @@ -962,11 +964,6 @@ where
payment.amount().into(),
memo.clone(),
)?;
orchard_output_meta.push((
Recipient::External(payment.recipient_address().clone(), *output_pool),
payment.amount(),
Some(memo),
));
}

PoolType::Shielded(ShieldedProtocol::Sapling) => {
Expand All @@ -976,11 +973,6 @@ where
payment.amount(),
memo.clone(),
)?;
sapling_output_meta.push((
Recipient::External(payment.recipient_address().clone(), *output_pool),
payment.amount(),
Some(memo),
));
}

PoolType::Transparent => {
Expand All @@ -1003,23 +995,13 @@ where
payment.amount(),
memo.clone(),
)?;
sapling_output_meta.push((
Recipient::External(payment.recipient_address().clone(), PoolType::SAPLING),
payment.amount(),
Some(memo),
));
}
Address::Transparent(to) => {
if payment.memo().is_some() {
return Err(Error::MemoForbidden);
} else {
builder.add_transparent_output(&to, payment.amount())?;
}
transparent_output_meta.push((
Recipient::External(payment.recipient_address().clone(), PoolType::TRANSPARENT),
to,
payment.amount(),
));
}
Address::Tex(_) => {
return Err(Error::ProposalNotSupported);
Expand All @@ -1036,19 +1018,10 @@ where
PoolType::Shielded(ShieldedProtocol::Sapling) => {
builder.add_sapling_output(
sapling_internal_ovk(),
sapling_dfvk.change_address().1,
override_sapling_change_address.unwrap_or(sapling_dfvk.change_address().1),
change_value.value(),
memo.clone(),
)?;
sapling_output_meta.push((
Recipient::InternalAccount {
receiving_account: account,
external_address: None,
note: output_pool,
},
change_value.value(),
Some(memo),
))
}
PoolType::Shielded(ShieldedProtocol::Orchard) => {
#[cfg(not(feature = "orchard"))]
Expand All @@ -1058,19 +1031,10 @@ where
{
builder.add_orchard_output(
orchard_internal_ovk(),
orchard_fvk.address_at(0u32, orchard::keys::Scope::Internal),
orchard_fvk.address_at(0u32, orchard::keys::Scope::External),
change_value.value().into(),
memo.clone(),
)?;
orchard_output_meta.push((
Recipient::InternalAccount {
receiving_account: account,
external_address: None,
note: output_pool,
},
change_value.value(),
Some(memo),
))
}
}
PoolType::Transparent => {
Expand All @@ -1082,110 +1046,6 @@ where
// Build the transaction with the specified fee rule
let build_result = builder.build(OsRng, spend_prover, output_prover, fee_rule)?;

#[cfg(feature = "orchard")]
let orchard_internal_ivk = orchard_fvk.to_ivk(orchard::keys::Scope::Internal);
#[cfg(feature = "orchard")]
let orchard_outputs =
orchard_output_meta
.into_iter()
.enumerate()
.map(|(i, (recipient, value, memo))| {
let output_index = build_result
.orchard_meta()
.output_action_index(i)
.expect("An action should exist in the transaction for each Orchard output.");

let recipient = recipient
.map_internal_account_note(|pool| {
assert!(pool == PoolType::ORCHARD);
build_result
.transaction()
.orchard_bundle()
.and_then(|bundle| {
bundle
.decrypt_output_with_key(output_index, &orchard_internal_ivk)
.map(|(note, _, _)| Note::Orchard(note))
})
})
.internal_account_note_transpose_option()
.expect("Wallet-internal outputs must be decryptable with the wallet's IVK");

SentTransactionOutput::from_parts(output_index, recipient, value, memo)
});

let sapling_internal_ivk =
PreparedIncomingViewingKey::new(&sapling_dfvk.to_ivk(Scope::Internal));
let sapling_outputs =
sapling_output_meta
.into_iter()
.enumerate()
.map(|(i, (recipient, value, memo))| {
let output_index = build_result
.sapling_meta()
.output_index(i)
.expect("An output should exist in the transaction for each Sapling payment.");

let recipient = recipient
.map_internal_account_note(|pool| {
assert!(pool == PoolType::SAPLING);
build_result
.transaction()
.sapling_bundle()
.and_then(|bundle| {
try_sapling_note_decryption(
&sapling_internal_ivk,
&bundle.shielded_outputs()[output_index],
zip212_enforcement(params, min_target_height),
)
.map(|(note, _, _)| Note::Sapling(note))
})
})
.internal_account_note_transpose_option()
.expect("Wallet-internal outputs must be decryptable with the wallet's IVK");

SentTransactionOutput::from_parts(output_index, recipient, value, memo)
});

let transparent_outputs =
transparent_output_meta
.into_iter()
.map(|(recipient, addr, value)| {
let script = addr.script();
let output_index = build_result
.transaction()
.transparent_bundle()
.and_then(|b| {
b.vout
.iter()
.enumerate()
.find(|(_, tx_out)| tx_out.script_pubkey == script)
})
.map(|(index, _)| index)
.expect(
"An output should exist in the transaction for each transparent payment.",
);

SentTransactionOutput::from_parts(output_index, recipient, value, None)
});

let mut outputs = vec![];
#[cfg(feature = "orchard")]
outputs.extend(orchard_outputs);
outputs.extend(sapling_outputs);
outputs.extend(transparent_outputs);

wallet_db
.store_sent_tx(&SentTransaction {
tx: build_result.transaction(),
created: time::OffsetDateTime::now_utc(),
account,
outputs,
fee_amount: proposal_step.balance().fee_required(),
#[cfg(feature = "transparent-inputs")]
utxos_spent,
})
.map_err(Error::DataSource)?;

Ok(build_result)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl<DE: fmt::Display, SE: fmt::Display> fmt::Display for InputSelectorError<DE,
InputSelectorError::DataSource(e) => {
write!(
f,
"The underlying datasource produced the following error: {}",
"The underlying data source produced the following error: {}",
e
)
}
Expand Down
Loading
Loading