Skip to content

Commit

Permalink
Merge pull request #1008 from fluidvanadium/propose
Browse files Browse the repository at this point in the history
Propose
  • Loading branch information
AloeareV authored Apr 29, 2024
2 parents 881e836 + 739f755 commit 08d1bdf
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 7 deletions.
79 changes: 74 additions & 5 deletions zingolib/src/lightclient/send.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
//! TODO: Add Mod Description Here!
use log::debug;

use zcash_client_backend::address::Address;
use zcash_client_backend::{
address::Address,
zip321::{Payment, TransactionRequest},
};
use zcash_primitives::{
consensus::BlockHeight,
memo::MemoBytes,
Expand All @@ -13,7 +16,40 @@ use super::{LightClient, LightWalletSendProgress};
use crate::{utils::zatoshis_from_u64, wallet::Pool};

#[cfg(feature = "zip317")]
use zcash_primitives::transaction::TxId;
use {
crate::{error::ZingoLibError, wallet::tx_map_and_maybe_trees::TxMapAndMaybeTrees},
std::{num::NonZeroU32, ops::DerefMut},
zcash_client_backend::{
data_api::wallet::input_selection::GreedyInputSelector, ShieldedProtocol,
},
zcash_primitives::transaction::TxId,
zingoconfig::ChainType,
};

#[cfg(feature = "zip317")]
type GISKit = GreedyInputSelector<
TxMapAndMaybeTrees,
zcash_client_backend::fees::zip317::SingleOutputChangeStrategy,
>;

/// converts from raw receivers to TransactionRequest
pub fn receivers_becomes_transaction_request(
receivers: Vec<(Address, NonNegativeAmount, Option<MemoBytes>)>,
) -> Result<TransactionRequest, zcash_client_backend::zip321::Zip321Error> {
let mut payments = vec![];
for out in receivers.clone() {
payments.push(Payment {
recipient_address: out.0,
amount: out.1,
memo: out.2,
label: None,
message: None,
other_params: vec![],
});
}

TransactionRequest::new(payments)
}

impl LightClient {
async fn get_submission_height(&self) -> Result<BlockHeight, String> {
Expand All @@ -30,11 +66,44 @@ impl LightClient {
#[cfg(feature = "zip317")]
pub async fn do_propose_spend(
&self,
_receivers: Vec<(Address, NonNegativeAmount, Option<MemoBytes>)>,
receivers: Vec<(Address, NonNegativeAmount, Option<MemoBytes>)>,
) -> Result<crate::data::proposal::TransferProposal, String> {
use crate::test_framework::mocks::ProposalBuilder;
let request =
receivers_becomes_transaction_request(receivers).map_err(|e| e.to_string())?;

let change_strategy = zcash_client_backend::fees::zip317::SingleOutputChangeStrategy::new(
zcash_primitives::transaction::fees::zip317::FeeRule::standard(),
None,
ShieldedProtocol::Orchard,
); // review consider change strategy!

let input_selector = GISKit::new(
change_strategy,
zcash_client_backend::fees::DustOutputPolicy::default(),
);

let mut tmamt = self
.wallet
.transaction_context
.transaction_metadata_set
.write()
.await;

let proposal = zcash_client_backend::data_api::wallet::propose_transfer::<
TxMapAndMaybeTrees,
ChainType,
GISKit,
ZingoLibError,
>(
tmamt.deref_mut(),
&self.wallet.transaction_context.config.chain,
zcash_primitives::zip32::AccountId::ZERO,
&input_selector,
request,
NonZeroU32::MIN, //review! use custom constant?
)
.map_err(|e| ZingoLibError::Error(format!("error this function todo error {:?}", e)))?;

let proposal = ProposalBuilder::default().build();
let mut latest_proposal_lock = self.latest_proposal.write().await;
*latest_proposal_lock = Some(crate::data::proposal::ZingoProposal::Transfer(
proposal.clone(),
Expand Down
2 changes: 1 addition & 1 deletion zingolib/src/wallet/transaction_records_by_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use zcash_primitives::consensus::BlockHeight;

use zcash_primitives::transaction::TxId;

mod trait_inputsource;
pub mod trait_inputsource;

use super::notes::query::OutputSpendStatusQuery;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl InputSource for TransactionRecordsById {
sources: &[zcash_client_backend::ShieldedProtocol],
anchor_height: zcash_primitives::consensus::BlockHeight,
exclude: &[Self::NoteRef],
) -> Result<SpendableNotes<NoteId>, InputSourceError> {
) -> Result<SpendableNotes<Self::NoteRef>, Self::Error> {
let mut sapling_note_noteref_pairs: Vec<(sapling_crypto::Note, NoteId)> = Vec::new();
let mut orchard_note_noteref_pairs: Vec<(orchard::Note, NoteId)> = Vec::new();
for transaction_record in self.values().filter(|transaction_record| {
Expand Down
5 changes: 5 additions & 0 deletions zingolib/src/wallet/tx_map_and_maybe_trees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,12 @@ impl TxMapAndMaybeTrees {
pub mod error {
use std::fmt::{Debug, Display, Formatter, Result};

use crate::wallet::transaction_records_by_id::trait_inputsource::error::InputSourceError;

#[derive(Debug, PartialEq)]
pub enum TxMapAndMaybeTreesError {
NoSpendCapability,
InputSource(InputSourceError),
}

impl From<&TxMapAndMaybeTreesError> for String {
Expand All @@ -59,6 +62,7 @@ pub mod error {
NoSpendCapability => {
"No witness trees. This is viewkey watch, not a spendkey wallet.".to_string()
}
InputSource(e) => e.to_string(),
};
format!("{:#?} - {}", value, explanation)
}
Expand All @@ -70,4 +74,5 @@ pub mod error {
}
}

pub mod trait_stub_inputsource;
pub mod trait_walletread;
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//! this mod brings input source functionality from transaction_records_by_id
use zcash_client_backend::{
data_api::{InputSource, SpendableNotes},
wallet::NoteId,
};

use super::{error::TxMapAndMaybeTreesError, TxMapAndMaybeTrees};

/// A trait representing the capability to query a data store for unspent transaction outputs belonging to a wallet.
/// combining this with WalletRead unlocks propose_transaction
/// all implementations in this file redirect to transaction_records_by_id
impl InputSource for TxMapAndMaybeTrees {
type Error = TxMapAndMaybeTreesError;
type AccountId = zcash_primitives::zip32::AccountId;
type NoteRef = NoteId;

fn get_spendable_note(
&self,
txid: &zcash_primitives::transaction::TxId,
protocol: zcash_client_backend::ShieldedProtocol,
index: u32,
) -> Result<
Option<
zcash_client_backend::wallet::ReceivedNote<
Self::NoteRef,
zcash_client_backend::wallet::Note,
>,
>,
Self::Error,
> {
self.transaction_records_by_id
.get_spendable_note(txid, protocol, index)
.map_err(TxMapAndMaybeTreesError::InputSource)
}

fn select_spendable_notes(
&self,
account: Self::AccountId,
target_value: zcash_primitives::transaction::components::amount::NonNegativeAmount,
sources: &[zcash_client_backend::ShieldedProtocol],
anchor_height: zcash_primitives::consensus::BlockHeight,
exclude: &[Self::NoteRef],
) -> Result<SpendableNotes<Self::NoteRef>, Self::Error> {
self.transaction_records_by_id
.select_spendable_notes(account, target_value, sources, anchor_height, exclude)
.map_err(TxMapAndMaybeTreesError::InputSource)
}

fn get_unspent_transparent_output(
&self,
outpoint: &zcash_primitives::transaction::components::OutPoint,
) -> Result<Option<zcash_client_backend::wallet::WalletTransparentOutput>, Self::Error> {
self.transaction_records_by_id
.get_unspent_transparent_output(outpoint)
.map_err(TxMapAndMaybeTreesError::InputSource)
}

fn get_unspent_transparent_outputs(
&self,
address: &zcash_primitives::legacy::TransparentAddress,
max_height: zcash_primitives::consensus::BlockHeight,
exclude: &[zcash_primitives::transaction::components::OutPoint],
) -> Result<Vec<zcash_client_backend::wallet::WalletTransparentOutput>, Self::Error> {
self.transaction_records_by_id
.get_unspent_transparent_outputs(address, max_height, exclude)
.map_err(TxMapAndMaybeTreesError::InputSource)
}
}

0 comments on commit 08d1bdf

Please sign in to comment.