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

Added batching using DB. #724

Merged
merged 1 commit into from
May 9, 2024
Merged

Conversation

piohei
Copy link
Contributor

@piohei piohei commented May 7, 2024

This is a first step to introduce batches and transactions table. This is not HA solution yet - just the first step towards it.

Motivation

Make small changes instead of one big.

Solution

Now processing batches is changed into 2 steps. First one is to create a batch (select identities, leaf indexes, etc.). Then the batch is saved in database. Second step is reading data from database (batch) and executes it. Proper batch execution includes storing transaction id in database.

As an alternative solution we could save in database a batch with a proves (no need to calculate it later). It will allow second step (transaction creation/execution) to not use any tree at all. It will require more memory used in database (it can be cleared from time to time as we don't need all the batches forever) but will make HA solution much easier.

PR Checklist

  • Added Tests
  • Added Documentation

@piohei piohei force-pushed the piohei/ha_step_1 branch from 81adc4d to cfff3ef Compare May 7, 2024 06:57
@@ -263,6 +263,9 @@ impl BasicTreeOps for TreeVersionData<lazy_merkle_tree::Derived> {
fn update(&mut self, leaf_index: usize, element: Hash) {
let updated_tree = self.tree.update(leaf_index, &element);

if self.tree.root() == updated_tree.root() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it here because of recreating tree on startup. It is hard to easily select from database proper groups of commitments. There are three options:

  1. As done change the code to not apply updates that don't change the tree at all. Why? Because then we are peeking changes to create a batch that are not changing anything and we can't put such a batch in database (unique/fk constraints).
  2. Instead of doing it here we can peek the "no-changing" changes and just not save them in database.
  3. Add additional internal status just for this "batched but not processed yet" situation.
  4. Do more queries on startup but may use much more memory as we are loading almost all commitments. :/

@@ -280,7 +283,25 @@ impl BasicTreeOps for TreeVersionData<lazy_merkle_tree::Derived> {
fn apply_diffs(&mut self, mut diffs: Vec<AppliedTreeUpdate>) {
let last = diffs.last().cloned();

self.metadata.diff.append(&mut diffs);
if !diffs.is_empty() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

latest: TreeVersion<Latest>,
mined: TreeVersion<Canonical>,
processed: TreeVersion<Intermediate>,
processed_batching: TreeVersion<Intermediate>,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This additional tree is required to generate proofs. We need a tree in a state when root is same as prev_root in batch. We can use batching tree as it is updated to create new batches (with proper leaf_indexes).

@piohei piohei marked this pull request as ready for review May 7, 2024 07:32
@piohei piohei requested a review from a team as a code owner May 7, 2024 07:32
batches.id as id,
batches.next_root as next_root,
batches.prev_root as prev_root,
batches.created_at as created_at,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK sqlx handles fully qualified names, so you can leave this (and others) as batches.created_at

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure I have done it due to created_at conflict but will reassure myself. :)

let batches = tx.get_all_batches_after(batch_entry.id).await?;
let mut result = vec![];
for batch in batches {
match batch.batch_type {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we have the same code for both cases? In case for deletion we replace *batch.commitments.0.get(i).unwrap() with Hash::ZERO but *batch.commitments.0.get(i).unwrap() should be zero anyway, no?

@piohei piohei force-pushed the piohei/ha_step_1 branch 2 times, most recently from 0c61b0c to b38c59f Compare May 9, 2024 05:04
@piohei piohei changed the title Added batching using DB. Additional tree added to have proper state on startup. Added batching using DB. May 9, 2024
@piohei piohei force-pushed the piohei/ha_step_1 branch from b38c59f to ad256dc Compare May 9, 2024 07:10
@Dzejkop Dzejkop merged commit f4fcc03 into worldcoin:main May 9, 2024
3 checks passed
Dzejkop added a commit that referenced this pull request May 14, 2024
Dzejkop added a commit that referenced this pull request May 14, 2024
@piohei piohei deleted the piohei/ha_step_1 branch June 24, 2024 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants