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

Batch insert #330

Merged
merged 59 commits into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
ae47774
checkpoint
SupremoUGH Mar 14, 2023
df6edd4
checkpoint
SupremoUGH Mar 15, 2023
164057a
checkpoint
SupremoUGH Mar 15, 2023
629bdec
Merge branch 'main' into signer_initial_sync_checkout
SupremoUGH Mar 15, 2023
60c5eb8
merkle tree functions
SupremoUGH Mar 15, 2023
6496e48
accumulator trait
SupremoUGH Mar 15, 2023
e6d73f9
signer functions
SupremoUGH Mar 15, 2023
8444d01
signer initial sync
SupremoUGH Mar 15, 2023
1c18f58
wallet has method as well
SupremoUGH Mar 15, 2023
091eb31
tests
SupremoUGH Mar 16, 2023
0c78f26
change dep
SupremoUGH Mar 16, 2023
be369ad
fixed dep
SupremoUGH Mar 16, 2023
8053258
dep
SupremoUGH Mar 16, 2023
ca0ad1d
rearranged tests
SupremoUGH Mar 17, 2023
9cc2e1f
restored cargo.toml
SupremoUGH Mar 17, 2023
68ce7ac
clippy
SupremoUGH Mar 17, 2023
d9c2a77
changed nullifier data and batched the initial sync
SupremoUGH Mar 17, 2023
e57d2b6
final design
SupremoUGH Mar 20, 2023
1d83f3c
export type CurrentPath
SupremoUGH Mar 20, 2023
976ae74
small error
SupremoUGH Mar 20, 2023
e16c651
debugging
SupremoUGH Mar 21, 2023
0c1506d
debug
SupremoUGH Mar 21, 2023
bcd0aff
debugging
SupremoUGH Mar 21, 2023
69a088b
changed default impl
SupremoUGH Mar 21, 2023
087e7b6
first round of corrections
SupremoUGH Mar 22, 2023
09b5969
debug removed
SupremoUGH Mar 22, 2023
aa4b43b
unused imports
SupremoUGH Mar 22, 2023
30fe0d8
simplified initial sync. added reset to initial sync
SupremoUGH Mar 22, 2023
c2a4610
simulation restored
SupremoUGH Mar 22, 2023
c3bd754
testing fixed
SupremoUGH Mar 22, 2023
c99cf89
test fixed
SupremoUGH Mar 22, 2023
8bd829c
fixed feature issue
SupremoUGH Mar 22, 2023
c87f67b
changelog
SupremoUGH Mar 22, 2023
91901de
signer method in wallet
SupremoUGH Mar 22, 2023
fe4ed12
Merge branch 'main' into signer_initial_sync_checkout
SupremoUGH Mar 23, 2023
090b67e
comments addressed
SupremoUGH Mar 24, 2023
e76bb56
inner tree logic
SupremoUGH Mar 24, 2023
b5d5bab
all trees take batch insertions
SupremoUGH Mar 27, 2023
840b0cc
impl for forest
SupremoUGH Mar 28, 2023
ba4a6d8
bug fixed
SupremoUGH Mar 28, 2023
1a358c7
test
SupremoUGH Mar 28, 2023
a0eaff6
test for forest
SupremoUGH Mar 28, 2023
5278015
remove debug
SupremoUGH Mar 28, 2023
6eaa823
signer updated
SupremoUGH Mar 28, 2023
2a9212b
small check
SupremoUGH Mar 28, 2023
909c3ba
merge
SupremoUGH Mar 28, 2023
725d813
batch_insert doesnt panic
SupremoUGH Mar 29, 2023
5259da7
docs
SupremoUGH Mar 29, 2023
476fcba
docs
SupremoUGH Mar 29, 2023
b11308c
batch insertion till full capacity
SupremoUGH Mar 29, 2023
d5bbb4a
changelog
SupremoUGH Mar 29, 2023
eecf9ff
truncate
SupremoUGH Mar 29, 2023
d4c8718
expose auth context
SupremoUGH Mar 29, 2023
d7977e1
comments addressed
SupremoUGH Apr 3, 2023
b12df28
try_load
SupremoUGH Apr 3, 2023
eb3b2f3
clippy
SupremoUGH Apr 3, 2023
c17e3b9
Merge branch 'main' into batch_insert
bhgomes Apr 4, 2023
7ff584a
merge main
SupremoUGH Apr 4, 2023
e43516e
comment addressed
SupremoUGH Apr 4, 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 @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]
### Added
- [\#330](https://github.com/Manta-Network/manta-rs/pull/330) Merkle tree batch insertions.

### Changed

Expand Down
14 changes: 12 additions & 2 deletions manta-accounting/src/wallet/signer/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ use crate::{
};
use alloc::{vec, vec::Vec};
use manta_crypto::{
accumulator::{Accumulator, FromItemsAndWitnesses, ItemHashFunction, OptimizedAccumulator},
accumulator::{
Accumulator, BatchInsertion, FromItemsAndWitnesses, ItemHashFunction, OptimizedAccumulator,
},
rand::Rand,
};
use manta_util::{
Expand Down Expand Up @@ -216,9 +218,14 @@ where
let mut deposit = Vec::new();
let mut withdraw = Vec::new();
let decryption_key = parameters.derive_decryption_key(authorization_context);
let mut nonprovable_inserts = Vec::new();
for (utxo, note) in inserts {
if let Some((identifier, asset)) = parameters.open_with_check(&decryption_key, &utxo, note)
{
if !nonprovable_inserts.is_empty() {
utxo_accumulator.batch_insert_nonprovable(&nonprovable_inserts);
nonprovable_inserts.clear();
}
insert_next_item::<C>(
authorization_context,
utxo_accumulator,
Expand All @@ -231,9 +238,12 @@ where
rng,
);
} else {
utxo_accumulator.insert_nonprovable(&item_hash::<C>(parameters, &utxo));
nonprovable_inserts.push(item_hash::<C>(parameters, &utxo));
}
}
if !nonprovable_inserts.is_empty() {
utxo_accumulator.batch_insert_nonprovable(&nonprovable_inserts);
}
assets.retain(|identifier, assets| {
assets.retain(|asset| {
is_asset_unspent::<C>(
Expand Down
42 changes: 36 additions & 6 deletions manta-accounting/src/wallet/signer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use alloc::{boxed::Box, vec::Vec};
use core::{convert::Infallible, fmt::Debug, hash::Hash};
use manta_crypto::{
accumulator::{
Accumulator, ExactSizeAccumulator, FromItemsAndWitnesses, ItemHashFunction,
Accumulator, BatchInsertion, ExactSizeAccumulator, FromItemsAndWitnesses, ItemHashFunction,
OptimizedAccumulator,
},
rand::{CryptoRng, FromEntropy, RngCore},
Expand Down Expand Up @@ -867,7 +867,8 @@ pub trait Configuration: transfer::Configuration {
Item = UtxoAccumulatorItem<Self>,
Model = UtxoAccumulatorModel<Self>,
Witness = UtxoAccumulatorWitness<Self>,
> + ExactSizeAccumulator
> + BatchInsertion
+ ExactSizeAccumulator
+ FromItemsAndWitnesses
+ OptimizedAccumulator
+ Rollback;
Expand Down Expand Up @@ -1074,6 +1075,19 @@ where
self.accounts = None
}

/// Tries to load `authorization_context_option` to `self`.
#[inline]
pub fn try_load_authorization_context(
&mut self,
authorization_context_option: Option<AuthorizationContext<C>>,
) -> bool {
if let Some(authorization_context) = authorization_context_option {
self.load_authorization_context(authorization_context);
return true;
}
false
}

/// Loads `authorization_context` to `self`.
#[inline]
pub fn load_authorization_context(&mut self, authorization_context: AuthorizationContext<C>) {
Expand All @@ -1088,14 +1102,14 @@ where

/// Returns the [`AccountTable`].
#[inline]
pub fn accounts(&self) -> &Option<AccountTable<C>> {
&self.accounts
pub fn accounts(&self) -> Option<&AccountTable<C>> {
self.accounts.as_ref()
}

/// Returns the [`AuthorizationContext`].
#[inline]
pub fn authorization_context(&self) -> &Option<AuthorizationContext<C>> {
&self.authorization_context
pub fn authorization_context(&self) -> Option<&AuthorizationContext<C>> {
self.authorization_context.as_ref()
}

/// Returns the default account for `self`.
Expand Down Expand Up @@ -1232,6 +1246,16 @@ where
self.state.drop_accounts()
}

/// Tries to load `authorization_context_option` to `self`.
#[inline]
pub fn try_load_authorization_context(
&mut self,
authorization_context_option: Option<AuthorizationContext<C>>,
) -> bool {
self.state
.try_load_authorization_context(authorization_context_option)
}

/// Loads `authorization_context` to `self`.
#[inline]
pub fn load_authorization_context(&mut self, authorization_context: AuthorizationContext<C>) {
Expand Down Expand Up @@ -1359,6 +1383,12 @@ where
))
}

/// Returns the [`AuthorizationContext`] corresponding to `self`.
#[inline]
pub fn authorization_context(&self) -> Option<&AuthorizationContext<C>> {
self.state.authorization_context.as_ref()
}

/// Returns the associated [`TransactionData`] of `post`, namely the [`Asset`] and the
/// [`Identifier`]. Returns `None` if `post` has an invalid shape, or if `self` doesn't own the
/// underlying assets in `post`.
Expand Down
51 changes: 51 additions & 0 deletions manta-crypto/src/accumulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,57 @@ pub trait OptimizedAccumulator: Accumulator {
}
}

/// Batch Insertion
pub trait BatchInsertion: OptimizedAccumulator {
/// Inserts `items` in `self` provably, see [`insert`] for more details.
/// Returns `true` if all the insertions succeed and `false` otherwise.
///
/// # Implementation Note
///
/// By default, this method calls [`insert`] individually for each item in `items`
/// till failure. Custom implementations of this method to improve performance
/// may insert a subset of `items` in case of failure.
///
/// [`insert`]: Accumulator::insert
#[inline]
fn batch_insert<'a, I>(&mut self, items: I) -> bool
where
Self::Item: 'a,
I: IntoIterator<Item = &'a Self::Item>,
{
for item in items {
if !self.insert(item) {
return false;
}
}
true
}

/// Inserts `items` in `self` nonprovably, see [`insert_nonprovable`] for more details.
/// Returns `true` if all the insertions succeed and `false` otherwise.
///
/// # Implementation Note
///
/// By default, this method calls [`insert_nonprovable`] individually for each item
/// in `items` till failure. Custom implementations of this method to improve performance
/// may insert a subset of `items` in case of failure.
///
/// [`insert_nonprovable`]: OptimizedAccumulator::insert_nonprovable
#[inline]
fn batch_insert_nonprovable<'a, I>(&mut self, items: I) -> bool
where
Self::Item: 'a,
I: IntoIterator<Item = &'a Self::Item>,
{
for item in items {
if !self.insert_nonprovable(item) {
return false;
}
}
true
}
}

/// From Items and Witnesses
pub trait FromItemsAndWitnesses: Accumulator {
/// Number of Subaccumulators
Expand Down
48 changes: 46 additions & 2 deletions manta-crypto/src/merkle_tree/forest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

use crate::{
accumulator::{
self, Accumulator, ConstantCapacityAccumulator, ExactSizeAccumulator,
self, Accumulator, BatchInsertion, ConstantCapacityAccumulator, ExactSizeAccumulator,
FromItemsAndWitnesses, MembershipProof, OptimizedAccumulator,
},
merkle_tree::{
Expand All @@ -37,7 +37,7 @@ use crate::{
},
};
use alloc::{boxed::Box, vec::Vec};
use core::{fmt::Debug, hash::Hash, marker::PhantomData};
use core::{fmt::Debug, hash::Hash, iter::Iterator, marker::PhantomData};
use manta_util::{persistence::Rollback, BoxArray};

#[cfg(feature = "serde")]
Expand Down Expand Up @@ -593,6 +593,50 @@ macro_rules! impl_from_items_and_witnesses {
result
}
}

impl<C, const N: usize> BatchInsertion for $forest
where
C: Configuration + ?Sized,
C::Index: FixedIndex<N>,
Parameters<C>: Clone,
Leaf<C>: Clone,
LeafDigest<C>: Clone + Default + PartialEq,
InnerDigest<C>: Clone + Default + PartialEq,
{
#[inline]
fn batch_insert<'a, I>(&mut self, items: I) -> bool
where
Self::Item: 'a,
I: IntoIterator<Item = &'a Self::Item>,
{
let mut result = true;
for (index, group) in Self::sort_items(items.into_iter().cloned().collect())
.into_iter()
.enumerate()
{
let tree = self.forest.get_mut(C::Index::from_index(index));
result &= tree.batch_push_provable(&self.parameters, &group);
}
result
}

#[inline]
fn batch_insert_nonprovable<'a, I>(&mut self, items: I) -> bool
where
Self::Item: 'a,
I: IntoIterator<Item = &'a Self::Item>,
{
let mut result = true;
for (index, group) in Self::sort_items(items.into_iter().cloned().collect())
.into_iter()
.enumerate()
{
let tree = self.forest.get_mut(C::Index::from_index(index));
result &= tree.batch_push(&self.parameters, &group);
}
result
}
}
};
}

Expand Down
72 changes: 72 additions & 0 deletions manta-crypto/src/merkle_tree/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,20 @@ where
self.data.push(parameters, leaf)
}

/// Appends `leaf_digests` onto this branch.
#[inline]
fn batch_maybe_push_digest<F>(
&mut self,
parameters: &Parameters<C>,
leaf_digests: F,
) -> Option<bool>
where
F: FnOnce() -> Vec<LeafDigest<C>>,
LeafDigest<C>: Default,
{
self.data.batch_maybe_push_digest(parameters, leaf_digests)
}

/// Appends a new `leaf_digest` onto this branch.
#[inline]
fn maybe_push_digest<F>(&mut self, parameters: &Parameters<C>, leaf_digest: F) -> Option<bool>
Expand Down Expand Up @@ -758,6 +772,25 @@ where
self.check_attachment()?;
self.branch.maybe_push_digest(parameters, leaf_digest)
}

/// Appends `leaf_digests` onto this fork.
///
/// Returns `None` if this fork has been detached from its trunk. Use [`attach`](Self::attach)
/// to re-associate a trunk to this fork.
#[inline]
pub fn batch_maybe_push_digest<F>(
&mut self,
parameters: &Parameters<C>,
leaf_digests: F,
) -> Option<bool>
where
F: FnOnce() -> Vec<LeafDigest<C>>,
LeafDigest<C>: Default,
{
self.check_attachment()?;
self.branch
.batch_maybe_push_digest(parameters, leaf_digests)
}
}

/// Forked Tree
Expand Down Expand Up @@ -908,6 +941,21 @@ where
self.branch.maybe_push_digest(parameters, leaf_digest)
}

/// Appends `leaf_digests` onto this forked tree.
#[inline]
fn batch_maybe_push_digest<F>(
&mut self,
parameters: &Parameters<C>,
leaf_digests: F,
) -> Option<bool>
where
F: FnOnce() -> Vec<LeafDigest<C>>,
LeafDigest<C>: Default,
{
self.branch
.batch_maybe_push_digest(parameters, leaf_digests)
}

/// Resets the fork of the base tree back to the trunk.
#[inline]
pub fn reset_fork(&mut self, parameters: &Parameters<C>)
Expand Down Expand Up @@ -992,6 +1040,18 @@ where
{
self.maybe_push_digest(parameters, leaf_digest)
}

#[inline]
fn batch_maybe_push_digest<F>(
&mut self,
parameters: &Parameters<C>,
leaf_digests: F,
) -> Option<bool>
where
F: FnOnce() -> Vec<LeafDigest<C>>,
{
self.batch_maybe_push_digest(parameters, leaf_digests)
}
}

impl<C, T, M> WithProofs<C> for ForkedTree<C, T, M>
Expand Down Expand Up @@ -1028,4 +1088,16 @@ where
fn path(&self, parameters: &Parameters<C>, index: usize) -> Result<Path<C>, PathError> {
self.path(parameters, index)
}

#[inline]
fn batch_maybe_push_provable_digest<F>(
&mut self,
parameters: &Parameters<C>,
leaf_digests: F,
) -> Option<bool>
where
F: FnOnce() -> Vec<LeafDigest<C>>,
{
self.batch_maybe_push_digest(parameters, leaf_digests)
}
}
Loading