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

To public optimization #356

Merged
merged 39 commits into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
45b874a
pruning fix
SupremoUGH May 31, 2023
29334a9
it works
SupremoUGH Jun 5, 2023
af61ea3
more things
SupremoUGH Jun 5, 2023
b7fea06
everything ready
SupremoUGH Jun 5, 2023
ceba725
everything ready
SupremoUGH Jun 5, 2023
32acf17
final touches
SupremoUGH Jun 5, 2023
58b3f61
changelog
SupremoUGH Jun 5, 2023
aedbd2c
clippy
SupremoUGH Jun 5, 2023
38c0942
final error found
SupremoUGH Jun 6, 2023
f8f06c6
no removing paths
SupremoUGH Jun 6, 2023
00b69fb
modified extend
SupremoUGH Jun 6, 2023
d158299
remove optimization
SupremoUGH Jun 6, 2023
70c7377
asset list method
SupremoUGH Jun 6, 2023
78d5e01
type asset_list_response
SupremoUGH Jun 6, 2023
1f925c5
asset list method takes normal ref
SupremoUGH Jun 6, 2023
4804bfb
asset list doesnt return zero assets
SupremoUGH Jun 7, 2023
23e5254
consolidation
SupremoUGH Jun 7, 2023
21039ad
consolidation prerequest
SupremoUGH Jun 7, 2023
b0ba214
clippy
SupremoUGH Jun 7, 2023
fd7f4bd
consolidation test
SupremoUGH Jun 8, 2023
034a2cc
test docs
SupremoUGH Jun 8, 2023
b8d3750
comment addressed
SupremoUGH Jun 9, 2023
f83ace6
Merge branch 'reinstore_pruning_good' into consolidate_utxos
SupremoUGH Jun 9, 2023
7673981
estimate posts
SupremoUGH Jun 9, 2023
888e915
docs and changelog
SupremoUGH Jun 9, 2023
ac92c05
docs
SupremoUGH Jun 9, 2023
9121a4a
docs
SupremoUGH Jun 9, 2023
98d9251
merge
SupremoUGH Jun 14, 2023
faf2599
estimate transferposts correction
SupremoUGH Jun 14, 2023
0be1ee2
done
SupremoUGH Jun 14, 2023
fbd5d4a
docs and changelog
SupremoUGH Jun 14, 2023
c7605ce
estimate posts update
SupremoUGH Jun 14, 2023
365169b
estimate again
SupremoUGH Jun 14, 2023
5c4920c
test
SupremoUGH Jun 14, 2023
ea23e3c
comments addressed
SupremoUGH Jun 15, 2023
a1eca87
final touch
SupremoUGH Jun 15, 2023
e415902
Merge branch 'consolidate_utxos' into to_public_optimization
SupremoUGH Jun 15, 2023
63fefbd
merge main
SupremoUGH Jun 16, 2023
0c58fe4
comments addressed
SupremoUGH Jun 19, 2023
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- [\#353](https://github.com/Manta-Network/manta-rs/pull/353) Restore Merkle tree pruning for the wallet.

### Changed
- [\#356](https://github.com/Manta-Network/manta-rs/pull/356) Signer ToPublic optimization.

### Deprecated

Expand Down
235 changes: 201 additions & 34 deletions manta-accounting/src/wallet/signer/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::{
batch::Join,
canonical::{
MultiProvingContext, PrivateTransfer, PrivateTransferShape, Selection, ToPrivate,
ToPublic, Transaction, TransactionData, TransferShape,
ToPublic, ToPublicShape, Transaction, TransactionData, TransferShape,
},
receiver::ReceiverPost,
requires_authorization,
Expand All @@ -45,6 +45,7 @@ use crate::{
},
};
use alloc::{vec, vec::Vec};
use core::ops::SubAssign;
use manta_crypto::{
accumulator::{
Accumulator, BatchInsertion, FromItemsAndWitnesses, ItemHashFunction, OptimizedAccumulator,
Expand Down Expand Up @@ -807,6 +808,137 @@ where
Ok(into_array_unchecked(final_presenders))
}

/// Performs a ToPublic transaction spending the assets in `selection`,
/// returning [`TransferPost`]s.
ghzlatarev marked this conversation as resolved.
Show resolved Hide resolved
#[allow(clippy::too_many_arguments)]
#[inline]
fn compute_to_public_transaction<C>(
accounts: &AccountTable<C>,
assets: &C::AssetMap,
parameters: &Parameters<C>,
proving_context: &MultiProvingContext<C>,
asset_id: &C::AssetId,
sink_accounts: Vec<C::AccountId>,
ghzlatarev marked this conversation as resolved.
Show resolved Hide resolved
selection: Selection<C>,
utxo_accumulator: &mut C::UtxoAccumulator,
rng: &mut C::Rng,
) -> Result<SignResponse<C>, SignError<C>>
where
C: Configuration,
C::AssetValue: SubAssign,
{
let Selection {
mut change,
mut pre_senders,
} = selection;
let mut posts = Vec::new();
let mut iter = pre_senders
.into_iter()
.chunk_by::<{ ToPublicShape::SENDERS }>();
for chunk in &mut iter {
let senders = array_map(chunk, |s| {
s.try_upgrade(parameters, utxo_accumulator)
.expect("Unable to upgrade expected UTXO.")
});
process_to_public_senders(
accounts,
parameters,
proving_context,
asset_id,
senders,
sink_accounts.clone(),
utxo_accumulator,
&mut change,
&mut posts,
rng,
)?;
}
pre_senders = iter.remainder();
if !pre_senders.is_empty() {
let final_senders = into_array_unchecked(prepare_final_pre_senders(
accounts,
assets,
utxo_accumulator,
parameters,
asset_id,
Default::default(),
pre_senders,
rng,
)?);
process_to_public_senders(
accounts,
parameters,
proving_context,
asset_id,
final_senders,
sink_accounts,
utxo_accumulator,
&mut change,
&mut posts,
rng,
)?;
}
Ok(SignResponse::new(posts))
}

/// Creates a to public [`TransferPost`] spending the assets held by `senders` and
/// attaches it to `post`.
#[allow(clippy::too_many_arguments)]
#[inline]
fn process_to_public_senders<C>(
accounts: &AccountTable<C>,
parameters: &Parameters<C>,
proving_context: &MultiProvingContext<C>,
asset_id: &C::AssetId,
senders: [Sender<C>; ToPublicShape::SENDERS],
sink_accounts: Vec<C::AccountId>,
utxo_accumulator: &mut C::UtxoAccumulator,
change: &mut C::AssetValue,
posts: &mut Vec<TransferPost<C>>,
rng: &mut C::Rng,
) -> Result<(), SignError<C>>
where
C: Configuration,
C::AssetValue: SubAssign,
{
let authorization = authorization_for_default_spending_key::<C>(accounts, parameters, rng);
let mut received_value = C::AssetValue::default();
ghzlatarev marked this conversation as resolved.
Show resolved Hide resolved
let mut reclaimed_value = senders
.iter()
.map(|sender| sender.asset().value)
.sum::<C::AssetValue>();
if reclaimed_value >= *change {
SupremoUGH marked this conversation as resolved.
Show resolved Hide resolved
received_value += change.clone();
reclaimed_value -= received_value.clone();
*change = Default::default();
} else {
received_value += reclaimed_value.clone();
*change -= reclaimed_value;
reclaimed_value = Default::default();
ghzlatarev marked this conversation as resolved.
Show resolved Hide resolved
}
let receiver = default_receiver::<C>(
accounts,
parameters,
Asset::<C>::new(asset_id.clone(), received_value),
rng,
);
posts.push(build_post(
Some(accounts),
utxo_accumulator.model(),
parameters,
&proving_context.to_public,
ToPublic::build(
authorization,
senders,
[receiver],
Asset::<C>::new(asset_id.clone(), reclaimed_value),
),
sink_accounts,
rng,
)?);
Ok(())
}

/// Returns the [`Address`] corresponding to `authorization_context`.
#[inline]
pub fn address<C>(
Expand Down Expand Up @@ -935,6 +1067,7 @@ fn sign_withdraw<C>(
) -> Result<SignResponse<C>, SignError<C>>
where
C: Configuration,
C::AssetValue: SubAssign,
{
let selection = select(accounts, assets, &parameters.parameters, &asset, rng)?;
sign_after_selection(
Expand Down Expand Up @@ -962,6 +1095,7 @@ fn consolidate_internal<C>(
) -> Result<SignResponse<C>, SignError<C>>
where
C: Configuration,
C::AssetValue: SubAssign,
C::Identifier: PartialEq,
{
let asset = request.asset();
Expand All @@ -979,18 +1113,16 @@ where
)
}

/// Signs a withdraw transaction for `asset` sent to `address`, where `selection`
/// owns at least `asset`.
/// Signs a private transfer of `asset` to `address`.
#[allow(clippy::too_many_arguments)]
#[inline]
fn sign_after_selection<C>(
fn sign_after_selection_private_transfer<C>(
parameters: &SignerParameters<C>,
accounts: &AccountTable<C>,
assets: &C::AssetMap,
utxo_accumulator: &mut C::UtxoAccumulator,
asset: Asset<C>,
address: Option<Address<C>>,
sink_accounts: Vec<C::AccountId>,
address: Address<C>,
selection: Selection<C>,
rng: &mut C::Rng,
) -> Result<SignResponse<C>, SignError<C>>
Expand All @@ -1017,37 +1149,68 @@ where
);
let authorization =
authorization_for_default_spending_key::<C>(accounts, &parameters.parameters, rng);
let final_post = match address {
Some(address) => {
let receiver = receiver::<C>(
&parameters.parameters,
address,
asset,
Default::default(),
rng,
);
build_post(
Some(accounts),
utxo_accumulator.model(),
&parameters.parameters,
&parameters.proving_context.private_transfer,
PrivateTransfer::build(authorization, senders, [change, receiver]),
Vec::new(),
rng,
)?
}
_ => build_post(
Some(accounts),
utxo_accumulator.model(),
let receiver = receiver::<C>(
&parameters.parameters,
address,
asset,
Default::default(),
rng,
);
let final_post = build_post(
Some(accounts),
utxo_accumulator.model(),
&parameters.parameters,
&parameters.proving_context.private_transfer,
PrivateTransfer::build(authorization, senders, [change, receiver]),
Vec::new(),
rng,
)?;
posts.push(final_post);
Ok(SignResponse::new(posts))
}

/// Signs a withdraw transaction for `asset` sent to `address`, where `selection`
/// owns at least `asset`.
#[allow(clippy::too_many_arguments)]
#[inline]
fn sign_after_selection<C>(
parameters: &SignerParameters<C>,
accounts: &AccountTable<C>,
assets: &C::AssetMap,
utxo_accumulator: &mut C::UtxoAccumulator,
asset: Asset<C>,
address: Option<Address<C>>,
sink_accounts: Vec<C::AccountId>,
selection: Selection<C>,
rng: &mut C::Rng,
) -> Result<SignResponse<C>, SignError<C>>
where
C: Configuration,
C::AssetValue: SubAssign,
{
match address {
Some(address) => sign_after_selection_private_transfer(
parameters,
accounts,
assets,
utxo_accumulator,
asset,
address,
selection,
rng,
),
_ => compute_to_public_transaction(
accounts,
assets,
&parameters.parameters,
&parameters.proving_context.to_public,
ToPublic::build(authorization, senders, [change], asset),
&parameters.proving_context,
&asset.id,
sink_accounts,
selection,
utxo_accumulator,
rng,
)?,
};
posts.push(final_post);
Ok(SignResponse::new(posts))
),
}
}

/// Signs the `transaction`, generating transfer posts without releasing resources.
Expand All @@ -1063,6 +1226,7 @@ fn sign_internal<C>(
) -> Result<SignResponse<C>, SignError<C>>
where
C: Configuration,
C::AssetValue: SubAssign,
{
match transaction {
Transaction::ToPrivate(asset) => {
Expand Down Expand Up @@ -1118,6 +1282,7 @@ pub fn sign<C>(
) -> Result<SignResponse<C>, SignError<C>>
where
C: Configuration,
C::AssetValue: SubAssign,
{
let result = sign_internal(
parameters,
Expand Down Expand Up @@ -1145,6 +1310,7 @@ pub fn consolidate<C>(
) -> Result<SignResponse<C>, SignError<C>>
where
C: Configuration,
C::AssetValue: SubAssign,
C::Identifier: PartialEq,
{
let result = consolidate_internal(
Expand Down Expand Up @@ -1270,6 +1436,7 @@ pub fn sign_with_transaction_data<C>(
) -> SignWithTransactionDataResult<C>
where
C: Configuration,
C::AssetValue: SubAssign,
TransferPost<C>: Clone,
{
Ok(SignWithTransactionDataResponse(
Expand Down
16 changes: 11 additions & 5 deletions manta-accounting/src/wallet/signer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use crate::{
wallet::ledger::{self, Data},
};
use alloc::{boxed::Box, vec::Vec};
use core::{cmp::max, convert::Infallible, fmt::Debug, hash::Hash};
use core::{cmp::max, convert::Infallible, fmt::Debug, hash::Hash, ops::SubAssign};
use manta_crypto::{
accumulator::{
Accumulator, BatchInsertion, ExactSizeAccumulator, FromItemsAndWitnesses, ItemHashFunction,
Expand Down Expand Up @@ -1640,7 +1640,10 @@ where

/// Signs the `transaction`, generating transfer posts.
#[inline]
pub fn sign(&mut self, transaction: Transaction<C>) -> Result<SignResponse<C>, SignError<C>> {
pub fn sign(&mut self, transaction: Transaction<C>) -> Result<SignResponse<C>, SignError<C>>
where
C::AssetValue: SubAssign,
{
functions::sign(
&self.parameters,
self.state.accounts.as_ref(),
Expand All @@ -1664,6 +1667,7 @@ where
request: ConsolidationPrerequest<C>,
) -> Result<SignResponse<C>, SignError<C>>
where
C::AssetValue: SubAssign,
C::Identifier: PartialEq,
{
functions::consolidate(
Expand Down Expand Up @@ -1741,6 +1745,7 @@ where
transaction: Transaction<C>,
) -> Result<SignWithTransactionDataResponse<C>, SignError<C>>
where
C::AssetValue: SubAssign,
TransferPost<C>: Clone,
{
functions::sign_with_transaction_data(
Expand Down Expand Up @@ -1835,16 +1840,17 @@ where
max(self.state.assets.select(asset).values.len() - 1, 1)
}
Transaction::ToPublic(asset, _) => {
max(self.state.assets.select(asset).values.len() - 1, 1)
} // note: change the estimation once we implement the topublic optimization
(self.state.assets.select(asset).values.len() + 1) / 2
}
}
}
}

impl<C> Connection<C> for Signer<C>
where
C: Configuration,
C::AssetValue: CheckedAdd<Output = C::AssetValue> + CheckedSub<Output = C::AssetValue>,
C::AssetValue:
CheckedAdd<Output = C::AssetValue> + CheckedSub<Output = C::AssetValue> + SubAssign,
C::Identifier: PartialEq,
{
type AssetMetadata = C::AssetMetadata;
Expand Down
Loading