-
Notifications
You must be signed in to change notification settings - Fork 270
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: showcase recursion case for transfer #7271
Changes from all commits
ec93f29
302ff84
c3c0f2f
44f8fbe
c3e601e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -295,7 +295,8 @@ contract Token { | |||||||||||
Option::none() | ||||||||||||
).set_limit(1); | ||||||||||||
let notes = pending_shields.get_notes(options); | ||||||||||||
let note = notes.get_unchecked(0); | ||||||||||||
assert(notes.len() == 1, "No pending shield found"); | ||||||||||||
let note = notes.get(0); | ||||||||||||
// Remove the note from the pending shields set | ||||||||||||
pending_shields.remove(note); | ||||||||||||
|
||||||||||||
|
@@ -335,13 +336,38 @@ contract Token { | |||||||||||
let to_ivpk = header.get_ivpk_m(&mut context, to); | ||||||||||||
|
||||||||||||
let amount = U128::from_integer(amount); | ||||||||||||
storage.balances.sub(from, amount).emit(encode_and_encrypt_note_with_keys_unconstrained(&mut context, from_ovpk, from_ivpk)); | ||||||||||||
let mut (change, missing) = storage.balances.odd_sub(from, amount, 2); | ||||||||||||
|
||||||||||||
// If we are still missing some balance to cover the amount, call accumulate to spend more notes. | ||||||||||||
let call = Token::at(context.this_address())._accumulate(from, missing.to_field()); | ||||||||||||
if !missing.eq(U128::zero()) { | ||||||||||||
change = call.call(&mut context); | ||||||||||||
} | ||||||||||||
|
||||||||||||
storage.balances.add(from, change).emit(encode_and_encrypt_note_with_keys_unconstrained(&mut context, from_ovpk, from_ivpk)); | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
storage.balances.add(to, amount).emit(encode_and_encrypt_note_with_keys_unconstrained(&mut context, from_ovpk, to_ivpk)); | ||||||||||||
|
||||||||||||
Transfer { from, to, amount: amount.to_field() }.emit(encode_and_encrypt_event_with_keys_unconstrained(&mut context, from_ovpk, to_ivpk)); | ||||||||||||
} | ||||||||||||
// docs:end:transfer | ||||||||||||
|
||||||||||||
/** | ||||||||||||
* Accumulate value by spending notes until we hit the missing amount | ||||||||||||
* If not enough notes are available, recurse to do it again. | ||||||||||||
* Will use MORE notes than the transfer directly since there are much smaller usual overhead on this function. | ||||||||||||
*/ | ||||||||||||
#[aztec(private)] | ||||||||||||
#[aztec(internal)] | ||||||||||||
fn _accumulate(owner: AztecAddress, missing_: Field) -> U128 { | ||||||||||||
// Since we are already spending a lot of doing the call, and we don't do anything else in here, we might as well go over more notes. | ||||||||||||
let mut (change, missing) = storage.balances.odd_sub(owner, U128::from_integer(missing_), 8); | ||||||||||||
let call = Token::at(context.this_address())._accumulate(owner, missing.to_field()); | ||||||||||||
if !missing.eq(U128::zero()) { | ||||||||||||
change = call.call(&mut context); | ||||||||||||
} | ||||||||||||
change | ||||||||||||
} | ||||||||||||
|
||||||||||||
/** | ||||||||||||
* Cancel a private authentication witness. | ||||||||||||
* @param inner_hash The inner hash of the authwit to cancel. | ||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -113,6 +113,39 @@ impl<T> BalancesMap<T, &mut PrivateContext> { | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.add(owner, minuend - subtrahend) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
pub fn odd_sub<T_SERIALIZED_LEN, T_SERIALIZED_BYTES_LEN>( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Claude ai generated nice docs here. BTW agree with Grego that |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
self: Self, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
owner: AztecAddress, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
subtrahend: U128, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
limit: u32 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> (U128, U128) where T: NoteInterface<T_SERIALIZED_LEN, T_SERIALIZED_BYTES_LEN> + OwnedNote { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend).set_limit(limit); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
let notes = self.map.at(owner).get_notes(options); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
assert(notes.len() > 0, "Balance too low"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
let mut minuend: U128 = U128::from_integer(0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
for i in 0..options.limit { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
if i < notes.len() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
let note = notes.get_unchecked(i); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Removes the note from the owner's set of notes. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
// This will call the the `compute_nullifer` function of the `token_note` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
// which require knowledge of the secret key (currently the users encryption key). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
// The contract logic must ensure that the spending key is used as well. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.map.at(owner).remove(note); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
minuend = minuend + note.get_amount(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
if minuend >= subtrahend { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
(minuend - subtrahend, U128::zero()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
(U128::zero(), subtrahend - minuend) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
pub fn filter_notes_min_sum<T, T_SERIALIZED_LEN, T_SERIALIZED_BYTES_LEN>( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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.
Could you explain here why we try to fetch only 2 notes? It would be very non-obvious to outsiders reading the code unless they are very knowledgeable about circuit optimization and we want the repo contracts to be an example.