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

refactor: storing &mut context in state vars #1926

Merged
merged 26 commits into from
Sep 4, 2023

Conversation

benesjan
Copy link
Contributor

@benesjan benesjan commented Sep 1, 2023

Fixes #1805

Note: I run the non-contract Noir files through rustfmt so some of the changes are purely formatting related.

Checklist:

Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge.

  • If the pull request requires a cryptography review (e.g. cryptographic algorithm implementations) I have added the 'crypto' tag.
  • I have reviewed my diff in github, line by line and removed unexpected formatting changes, testing logs, or commented-out code.
  • Every change is related to the PR description.
  • I have linked this pull request to relevant issues (if any exist).

@benesjan benesjan marked this pull request as draft September 1, 2023 09:22
@benesjan benesjan force-pushed the janb/storing-context-in-state-vars branch from 1978f38 to 3754c87 Compare September 1, 2023 15:01
@benesjan benesjan marked this pull request as ready for review September 1, 2023 15:22
@benesjan benesjan enabled auto-merge (squash) September 1, 2023 15:23
@iAmMichaelConnor
Copy link
Contributor

Thanks very much for this @benesjan
I think this will make the syntax look very pretty indeed, when we're able to "hide" the Storage::init(...) call using Sean's new macro approach.

I just merged a big PR from Leila, which adds lots of docs relating to state variables and storage syntax. Please can you rebase and maybe search for new instances of Storage::init which might need to be updated in the example code which gets embedded into the new docs?

@benesjan
Copy link
Contributor Author

benesjan commented Sep 1, 2023

I just merged a big PR from Leila, which adds lots of docs relating to state variables and storage syntax. Please can you rebase and maybe search for new instances of Storage::init which might need to be updated in the example code which gets embedded into the new docs?

@iAmMichaelConnor Just finished doing all the changes.

Copy link
Collaborator

@spalladino spalladino left a comment

Choose a reason for hiding this comment

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

Amazing work Jan, thanks for taking this on!

}
// docs:end:state_vars-check_return_notes

// docs:start:functions-UncontrainedFunction
unconstrained fn get_total_points(account: Field) -> u8 {
let storage = Storage::init();
let storage = Storage::init(Option::none(), Option::none());
Copy link
Collaborator

Choose a reason for hiding this comment

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

I was going to suggest adding a method like Storage::init_view() that didn't take any params and set both Option::nones under the hood. But if we're going to hide this behind a macro, no need to polish it up, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I think it doesn't make sense to implement because of the macro. It would just make Storage a bit more complex and the gain would not be there.

use dep::aztec::context::{
PrivateContext,
};
use dep::aztec::constants_gen::{MAX_NOTES_PER_PAGE, MAX_READ_REQUESTS_PER_CALL};
Copy link
Collaborator

Choose a reason for hiding this comment

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

Did you run a code formatter or something? If so, how? We should get it into the CI so we ensure all our code gets formatted.

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 used rustfmt but it was a semi-manual process because rustfmt fails on unconstrained methods and global vars. How I made it work is that I first renamed unconstrained get_balance to get_balance_unconstrained and removed the global vars and then reverted the changes. The formatting became too ugly so it was worth the hassle but this makes it impossible to use in CI without bigger modifications of rustfmt.

But this actually makes me curious whether to create noirfmt it would be sufficient to create some simple pre and post processors which would make and revert the changes I did manually... 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

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

FWIW I found a tracking issue in Noir, which doesn't seem prioritised atm: noir-lang/noir#1580

As for using rustfmt, it's an interesting idea, but I'm worried that it'll keep diverging as we add more non-rust features to Noir. Also, removing noir-specific keywords is easy, but adding them back is not, given the file changes introduced by rustfmt. I think we should probably wait.


// Emit the newly created encrypted note preimages via oracle calls.
let owner_key = get_public_key(owner);
let _context = self.context.unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: avoid using variable names starting with underscore, since they are (or are in most languages, not sure if Rust also) skipped for unused variable checks. As an alternative, you can rename the field to maybeContext, and the unwrapped version to context.

Comment on lines +14 to +16
// Note: Passing the contexts to new(...) just to have an interface compatible with a Map.
_: Option<&mut PrivateContext>,
_: Option<&mut PublicContext>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm on the fence about this: should we pass both optional contexts to every state var type? Or just the ones they actually need, like in ImmutableSingleton? Still, when we introduce traits, this problem will go away.

@benesjan benesjan merged commit 89a7a3f into master Sep 4, 2023
2 checks passed
@benesjan benesjan deleted the janb/storing-context-in-state-vars branch September 4, 2023 11:49
Comment on lines +13 to +26
fn init(
private_context: Option<&mut PrivateContext>,
public_context: Option<&mut PublicContext>,
) -> Self {
Storage {
balances: Map::new(1, |s| Set::new(s, ValueNoteMethods)),
claims: Set::new(2, ClaimNoteMethods),
balances: Map::new(
private_context,
public_context,
1, // Storage slot
|private_context, public_context, slot| {
Set::new(private_context, public_context, slot, ValueNoteMethods)
},
),
claims: Set::new(private_context, public_context, 2, ClaimNoteMethods),
Copy link
Contributor

Choose a reason for hiding this comment

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

I hadn't appreciated how ugly storage declarations would become with this new change. Declaring storage like this doesn't make for a very nice user experience, does it? (I know I initially proposed the change, to clean up calls to methods (by removing the context as a parameter to those calls)... but this is an ugly trade off, and I'm not sure if it's a good one, in hindsight).
I returned to this PR after a breaking change was flagged on discord @benesjan @spalladino - this PR caused a breaking change to storage declarations, and someone was struggling with declaring a double-mapping with this new syntax (and I can understand why :) )

Copy link
Contributor

@iAmMichaelConnor iAmMichaelConnor Sep 5, 2023

Choose a reason for hiding this comment

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

Declaring a double mapping has become this monstrosity, haha:

Storage {
    double_mapping: Map::new(
        private_context,
        public_context,
        1,
        |private_context, public_context, slot1| Map::new(
            private_context,
            public_context,
            slot1,
            |private_context, public_context, slot2| Set::new(
                private_context,
                public_context,
                slot2,
                ValueNoteMethods
            )
        )
    )
}

This might have to be classified as "unacceptable syntax"?

Edit: especially when compared to: mapping(uint256 => mapping(uint256 => uint256)) doubleMapping; in Solidity.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Agree it's horrible, but bear in mind that, as soon as we get traits, we can work with a single context. So the example above would become this. And we can even introduce a DoubleMap struct that abstracts it if we wanted to.

Storage {
    double_mapping: Map::new(context, 1,
        |context, slot1| Map::new(context, slot1, 
            |context, slot2| Set::new(context, slot2, ValueNoteMethods)
        )
    )
}

I still think the change is worth it. I'd expect developers to spend more time in contract logic that in storage declaration. And by moving the context into storage initialisation (which we can then hide with a macro), we can keep moving explicit references to context out of the picture, for cleaner contract code.

TLDR: Can you push the Noir team to get traits implemented soon? :-P

Copy link
Contributor

@iAmMichaelConnor iAmMichaelConnor Sep 5, 2023

Choose a reason for hiding this comment

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

I don't think they'll be implemented for some weeks (at the earliest). Perhaps we could wrap the private_context, public_context "tuple" in a Context type, just to reduce the verbosity of this.

struct Context {
    private_context: Option<PrivateContext>,
    public_context: Option<PublicContext>,
    _is_private: bool
}

And then pass this ugly thing between state variables instead?

A double mapping is a nice idea too!

Copy link
Contributor

Choose a reason for hiding this comment

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

TLDR: Can you push the Noir team to get traits implemented soon? :-P

I just asked, for you:
image

Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps we could wrap the private_context, public_context "tuple" in a Context type, just to reduce the verbosity of this.

I think that sould be easy to do (annoying, but easy) until we do get traits. Do you want to create an issue and assign it to Otters?

PhilWindle pushed a commit that referenced this pull request Sep 5, 2023
🤖 I have created a new Aztec Packages release
---


##
[0.1.0-alpha50](v0.1.0-alpha49...v0.1.0-alpha50)
(2023-09-05)


### ⚠ BREAKING CHANGES

* update to acvm 0.24.0
([#1925](#1925))

### Features

* **892:** add hints for matching transient read requests with
correspondi…
([#1995](#1995))
([0955bb7](0955bb7))
* Add support for assert messages & runtime call stacks
([#1997](#1997))
([ac68837](ac68837))
* **Aztec.nr:** Kernel return types abstraction
([#1924](#1924))
([3a8e702](3a8e702))
* **ci:** use content hash in build system, restrict docs build to *.ts
or *.cpp
([#1953](#1953))
([0036e07](0036e07))
* do not allow slot 0 in `noir-libs`
([#1884](#1884))
([54094b4](54094b4)),
closes
[#1692](#1692)
* throwing when submitting a duplicate tx of a settled one
([#1880](#1880))
([9ad768f](9ad768f)),
closes
[#1810](#1810)
* typos, using Tx.clone functionality, better naming
([#1976](#1976))
([00bca67](00bca67))


### Bug Fixes

* add retry_10 around ensure_repo
([#1963](#1963))
([0afde39](0afde39))
* Adds Mac cross compile flags into barretenberg
([#1954](#1954))
([3aaf91e](3aaf91e))
* bb meta-data
([#1960](#1960))
([712e0a0](712e0a0))
* **bb.js:** (breaking change) bundles bb.js properly so that it works
in the browser and in node
([#1855](#1855))
([1aa6f59](1aa6f59))
* Benchmark preset uses clang16
([#1902](#1902))
([4f7eeea](4f7eeea))
* build
([#1906](#1906))
([8223be1](8223be1))
* **ci:** Incorrect content hash in some build targets
([#1973](#1973))
([0a2a515](0a2a515))
* circuits should not link openmp with -DMULTITHREADING
([#1929](#1929))
([cd1a685](cd1a685))
* compilation on homebrew clang 16.06
([#1937](#1937))
([c611582](c611582))
* docs preprocessor line numbers and errors
([#1883](#1883))
([4e7e290](4e7e290))
* ensure CLI command doesn't fail due to missing client version
([#1895](#1895))
([88086e4](88086e4))
* error handling in acir simulator
([#1907](#1907))
([165008e](165008e))
* Fix off by one in circuits.js when fetching points from transcript
([#1993](#1993))
([cec901f](cec901f))
* format.sh issues
([#1946](#1946))
([f24814b](f24814b))
* master
([#1981](#1981))
([6bfb053](6bfb053))
* More accurate c++ build pattern
([#1962](#1962))
([21c2f8e](21c2f8e))
* polyfill by bundling fileURLToPath
([#1949](#1949))
([1b2de01](1b2de01))
* Set correct version of RPC & Sandbox when deploying tagged commit
([#1914](#1914))
([898c50d](898c50d))
* typescript lookup of aztec.js types
([#1948](#1948))
([22901ae](22901ae))
* unify base64 interface between mac and linux (cherry-picked)
([#1968](#1968))
([ee24b52](ee24b52))
* Update docs search config
([#1920](#1920))
([c8764e6](c8764e6))
* update docs search keys
([#1931](#1931))
([03b200c](03b200c))


### Miscellaneous

* **1407:** remove forwarding witnesses
([#1930](#1930))
([cc8bc8f](cc8bc8f)),
closes
[#1407](#1407)
* **1879:** add use of PrivateKernelPublicInputs in TS whenever relevant
([#1911](#1911))
([8d5f548](8d5f548))
* acir tests are no longer base64 encoded
([#1854](#1854))
([7fffd16](7fffd16))
* Add back double verify proof to test suite
([#1986](#1986))
([f8688d7](f8688d7))
* add CLI test to canary flow
([#1918](#1918))
([cc68958](cc68958)),
closes
[#1903](#1903)
* Add safemath noir testing
([#1967](#1967))
([cb1f1ec](cb1f1ec))
* **Aztec.nr:** remove implicit imports
([#1901](#1901))
([c7d5190](c7d5190))
* **Aztec.nr:** Remove the open keyword from public functions
([#1917](#1917))
([4db8603](4db8603))
* **ci:** build docs on every pr
([#1955](#1955))
([c200bc5](c200bc5))
* Enable project-specific releases for dockerhub too
([#1721](#1721))
([5d2c082](5d2c082))
* reduce max circuit size in bb binary
([#1942](#1942))
([c61439b](c61439b))
* Reference noir master for acir tests
([#1969](#1969))
([86b72e1](86b72e1))
* remove debug output from `run_acir_tests` script
([#1970](#1970))
([74c83c5](74c83c5))
* storing `&mut context` in state vars
([#1926](#1926))
([89a7a3f](89a7a3f)),
closes
[#1805](#1805)
* sync bb master
([#1947](#1947))
([eed58e1](eed58e1))
* update to acvm 0.24.0
([#1925](#1925))
([e728304](e728304))
* Update to acvm 0.24.1
([#1978](#1978))
([31c0a02](31c0a02))
* updating docs to clang16
([#1875](#1875))
([a248dae](a248dae))


### Documentation

* **keys:** Complete addresses are now broadcast
([#1975](#1975))
([92068ad](92068ad)),
closes
[#1936](#1936)
* limitations, privacy, roadmap
([#1759](#1759))
([0cdb27a](0cdb27a))
* put dev docs before spec
([#1944](#1944))
([f1b29cd](f1b29cd))
* storage and state variables
([#1725](#1725))
([fc72f84](fc72f84))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Pass &mut context to Storage::init and store a mutable ref to context in all state variables.
3 participants