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

Optimize check owned by removing json and fix double rkyv serialization bug #115

Merged
merged 11 commits into from
Jun 12, 2024

Conversation

Daksh14
Copy link
Contributor

@Daksh14 Daksh14 commented May 31, 2024

Closes #113 and #114

This is the wasm binary that is in the latest dusk-wallet-js version, we should merge into main ASAP

@Daksh14 Daksh14 changed the title Fix #113 and #113 Optimize check owned by removing json and fix double rkyv serialization bug May 31, 2024
Copy link
Contributor

@ZER0 ZER0 left a comment

Choose a reason for hiding this comment

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

Overall looks good, but there are few nits to change, one very important tied to performance and scalar multiplication.

CHANGELOG.md Outdated Show resolved Hide resolved
Cargo.toml Show resolved Hide resolved
src/compat/crypto.rs Outdated Show resolved Hide resolved
src/compat/crypto.rs Outdated Show resolved Hide resolved
src/compat/crypto.rs Outdated Show resolved Hide resolved
src/compat/crypto.rs Show resolved Hide resolved
src/compat/crypto.rs Outdated Show resolved Hide resolved
tests/wallet.rs Outdated Show resolved Hide resolved
@Daksh14 Daksh14 requested a review from ZER0 May 31, 2024 17:27
Copy link
Contributor

@ZER0 ZER0 left a comment

Choose a reason for hiding this comment

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

Still few things to change, but we're on the right track. Be sure to do not derive the keys inside any loops, but doing so upfront. If we notice this as common pattern, (the need of sk and vk together), we might also have an inline function that does that for us, so we don't have to repeat it.

CHANGELOG.md Outdated Show resolved Hide resolved
src/compat/crypto.rs Outdated Show resolved Hide resolved
src/compat/crypto.rs Outdated Show resolved Hide resolved
src/compat/crypto.rs Show resolved Hide resolved
src/compat/crypto.rs Show resolved Hide resolved
src/ffi.rs Show resolved Hide resolved
src/ffi.rs Show resolved Hide resolved
src/ffi.rs Outdated Show resolved Hide resolved
src/ffi.rs Outdated Show resolved Hide resolved
tests/wallet.rs Outdated
@@ -336,7 +336,7 @@ mod node {
.into_iter()
.map(|value| {
let obfuscated = (rng.next_u32() & 1) == 1;
let idx = rng.next_u64() % MAX_KEY as u64;
let idx = rng.next_u64() % (MAX_KEY) as u64;
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need to wrap the MAX_KEY in parentheses, the previous code would works fine.

@Daksh14 Daksh14 requested a review from ZER0 June 7, 2024 13:41
Copy link
Contributor

@ZER0 ZER0 left a comment

Choose a reason for hiding this comment

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

There is the part related to the loops and labels usage (see the comment). Once it's fixed I will approve immediately (that loop and others like that).

I would suggest to fix it in this PR to avoid open a separate issue, but if you're more comfortable to file a new issue and fix it there immediately please file the issue and add its link as reply to the conversation in this review concerning the matter; I'm also fine with that as soon as it's fixed ASAP.

src/ffi.rs Outdated
let sks: [SecretKey; MAX_KEY] =
core::array::from_fn(|i| key::derive_sk(&seed, i as _));
let vks: [ViewKey; MAX_KEY] =
core::array::from_fn(|i| key::derive_vk(&seed, i as _));

'outer: for note in notes {
Copy link
Contributor

Choose a reason for hiding this comment

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

You still didn't modify this loop as discussed.

  1. The comment is wrong, or best case scenario misleading
  2. The usage of labels makes the flow harder to follow from top to bottom – it's "GOTO-like" –; therefore the labels should be used only when there is not any decent alternative available
  3. Due to the label usage, the code makes use of a temp var called keys_len that shouldn't be there.

All those should be fixed, if you don't want to do it in this PR feel free to open immediately a new one – but also an issue related to that – to apply those changes. I suggested to do it in this PR since you're already touching this code and in addition you can skip to create a separate issue. But if you prefer to file a new issue and fix it immediately in a new PR, it's also fine.

My suggestion, as I already mentioned to you, would be modify this using a more functional approach with try_fold. Here is the code:

    let nullifiers = notes.iter().try_fold(
        Vec::with_capacity(notes.len()),
        |mut nullifiers, note| {
            if let Some(idx) = (0..MAX_KEY).find(|&i| vks[i].owns(note)) {
                let nullifier = note.gen_nullifier(&sks[idx]);
                nullifiers.push(nullifier);
                Ok(nullifiers)
            } else {
                Err(())
            }
        },
    );

    match nullifiers {
        Ok(n) => utils::rkyv_into_ptr(n),
        Err(_) => utils::fail(),
    }

Basically, if you cannot decrypt a note with any of the keys you own, than the function calls utils::fail.

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 removed the comment and the label, I think any greater refractor than that would be counter productive since the "big" refractor is imminent, I have already created the EPIC for refractor I'll add this content to it
#117

Copy link
Contributor

@ZER0 ZER0 left a comment

Choose a reason for hiding this comment

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

LGTM, just few minor nits before merging. See the comments, but to summarize:

  1. rename vk_idx into idx
  2. remove the unused core::mem as stated by github too.
  3. remove the sorrounding parentheses from MAX_KEY from tests.

src/ffi.rs Outdated
}
}
for note in notes {
let Some(vk_idx) = vks.iter().position(|vk| vk.owns(&note)) else {
Copy link
Contributor

Choose a reason for hiding this comment

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

I forgot about position, this is much better. Just call it idx or i.

@Daksh14 Daksh14 merged commit 27aa129 into main Jun 12, 2024
4 checks passed
@Daksh14 Daksh14 deleted the check_owned_fix branch June 12, 2024 03:39
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.

Double rkyv serialization in compat/rkyv.rs
2 participants