-
Notifications
You must be signed in to change notification settings - Fork 266
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
Conversation
1978f38
to
3754c87
Compare
Thanks very much for this @benesjan 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 |
@iAmMichaelConnor Just finished doing all the changes. |
There was a problem hiding this 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()); |
There was a problem hiding this comment.
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::none
s under the hood. But if we're going to hide this behind a macro, no need to polish it up, right?
There was a problem hiding this comment.
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}; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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... 🤔
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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
.
// Note: Passing the contexts to new(...) just to have an interface compatible with a Map. | ||
_: Option<&mut PrivateContext>, | ||
_: Option<&mut PublicContext>, |
There was a problem hiding this comment.
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.
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), |
There was a problem hiding this comment.
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 :) )
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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?
🤖 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>
Fixes #1805
Checklist:
Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge.