-
Notifications
You must be signed in to change notification settings - Fork 310
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
feat: bridge l1 assets to l2 acvm #578
Conversation
fix: rename
{ | ||
NT::fr message_secret; | ||
read(secret, message_secret); | ||
// TODO(sean): This is not using the generator correctly and is unsafe, update |
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.
wdym? does this have an issue we are tracking it in?
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.
Think it is because Noir currently does not support the generators specified as we are doing in cpp. The message_secret
is to be used in noir, so @Maddiaa0 using this method to have a hash that can be reproduced inside and outside noir.
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.
It's todo with not being able to use pedersen generator indexes natively inside noir yet.
- [index, ...hashValues], is not the same as [hashValues], hashed under a different generator index.
Alvaro has added the functionality to noir but it has not made it into the aztec3 branch yet so cannot be used here, (branch: https://github.com/noir-lang/noir/tree/arv/pedersen_with_hash_index)
I've made an issue for this here: #610
@@ -0,0 +1,22 @@ | |||
// SPDX-License-Identifier: Apache-2.0 |
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.
why do you have 2 IInbox interfaces?
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.
Seems this was left over from the merge, as your previous pr had it in a different location it did not cop (me also) that they were really the same file.
This has been addressed and they have been removed
|
||
// Check that the message is in the inbox | ||
IMessageBox.Entry memory entry = IInbox(inbox).get(entryKey); | ||
assertEq(entry.count, 1); |
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; you may also check if the corresponding event (MessageAdded
) got fired
let recipientPk: Buffer; | ||
let recipient: NoirPoint; | ||
|
||
const buildMessage = async (content: Fr[], targetContract: AztecAddress, secret: Fr) => { |
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: rename this to buildL1ToL2Message
AztecAddress.random(), | ||
contractAddress, | ||
new FunctionData(Buffer.alloc(4), true, true), | ||
// BUG: placing a fr in args will result in a fr wrapped in an fr |
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.
have you flagged this issue somewhere?
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.
Ah I have not, but it is a known issue, #611 made this for tracking
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.
If you put the issue in the comment would be neat 👍
@@ -216,6 +223,7 @@ export class PrivateFunctionExecution { | |||
private writeInputs() { | |||
const argsSize = this.abi.parameters.reduce((acc, param) => acc + sizeOfType(param.type), 0); | |||
|
|||
console.log('storage contract address: ', this.callContext.storageContractAddress); |
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: remove
|
||
global Nonce = 1; | ||
global NoteHash = 2; | ||
global NoteStorageSlot = 3; | ||
global MappingStorageSlot = 4; | ||
global Nullifier = 5; | ||
global L1ToL2MessageSecret = 29; |
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 am out of the loop - why is this 29? is this the pedereson generator constant?
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.
Its index 29 here:
L1_TO_L2_MESSAGE_SECRET |
secret: pub Field, | ||
) -> pub [Field; dep::aztec3::abi::PUBLIC_INPUTS_LENGTH] { | ||
let mut context = PrivateFunctionContext::new(); | ||
context.args = context.args.push_array([amount, owner.x, owner.y, msg_key, secret]); |
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.
damn is this how we create private vars in noir now?
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.
haha, nah its just to get around a noir mutability quirk when constructing the context for the kernel circuit
|
||
// Checks is a msg is within the l1Msg tree | ||
#[oracle(getL1ToL2Message)] | ||
fn get_l1_to_l2_msg_oracle(_msg_key: Field) -> [Field; L1_MESSAGE_ORACLE_CALL_LENGTH] {} |
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.
question so I understand this better -> how does this work?
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.
In the acvm you can register callbacks:
export interface ACIRCallback { |
When making an oracle call, it will look for the callback with the given name, then inject into this function response / send the inputs to the ts context. You can see in the tests where you can mock what the function returns.
hash_bytes[30] = amount_bytes[30]; | ||
hash_bytes[31] = amount_bytes[31]; | ||
|
||
hash_bytes[0 + 32] = recipient_bytes[0]; |
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.
BAHAHHAHAH damn :/
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.
fr fr
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.
A bit inconsistenct on L1 or L1ToL2 naming, but nice job 👍
l1-contracts/foundry.toml
Outdated
"@aztec/verifier/=lib/aztec-verifier-contracts/src/" | ||
"@aztec/interfaces/=src/interfaces/", | ||
"@aztec/verifier/=lib/aztec-verifier-contracts/src/", | ||
"@aztec/mocks/=/src/mock/" |
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.
This seems strange. Why is there both a mock
and mocks
now? And the interfaces don't seem to exist here, is in the core/interfaces
?
l1-contracts/src/core/Rollup.sol
Outdated
@@ -9,6 +9,11 @@ import {IOutbox} from "@aztec/core/interfaces/messagebridge/IOutbox.sol"; | |||
import {MockVerifier} from "@aztec/mock/MockVerifier.sol"; | |||
import {Decoder} from "./Decoder.sol"; | |||
|
|||
// Messaging |
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.
Think this needs a rebase to get the updates from #609
@@ -3,6 +3,9 @@ | |||
pragma solidity >=0.8.18; | |||
|
|||
library DataStructures { | |||
// Prime field modulus |
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.
Think this is more fitting in a Constants.sol
as it is not a data structure. In #552 I added one after your comment.
{ | ||
// Preamble | ||
IInbox inbox = REGISTRY.getInbox(); | ||
DataStructures.L2Actor memory actor = DataStructures.L2Actor(_to, 1); |
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.
Using the same _to
here means that the messages is received by the same as will be receiving funds. Won't you just lock the funds forever in the rollup to belong to the token contract itself.
Think the L2Actor
aztec address should not be specified by the user, but from storage in the contract, e.g., use an initialize function or something for making the "link" to the L2 contract and use that value for the actor, then the user passed in _to
can be part of the content.
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.
Yep, this is correct
* @param msgKey - A buffer representing the message key. | ||
* @returns The message data | ||
*/ | ||
public async getL1ToL2Message(msgKey: Fr) { |
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.
A specified return type would be neat.
// Deposit tokens to the TokenPortal | ||
const contractString = deployedContract.address.toString() as `0x${string}`; | ||
const secretString = `0x${claimSecretHash.toBuffer().toString('hex')}` as `0x${string}`; | ||
const deadline = 4_294_967_295 - 1; // max uint - 1 |
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.
Why do you want max uint - 1? The maxuint is already 2**32 - 1
"noir:build:test": "(cd src/contracts/test_contract && nargo compile main --contracts) && ts-node --esm src/scripts/copy_output.ts test", | ||
"noir:build:parent": "(cd src/contracts/parent_contract && nargo compile main --contracts) && ts-node --esm src/scripts/copy_output.ts parent", | ||
"noir:build:child": "(cd src/contracts/child_contract && nargo compile main --contracts) && ts-node --esm src/scripts/copy_output.ts child", | ||
"noir:build:zk_token": "(cd src/contracts/zk_token_contract && nargo compile main --contracts) && ts-node --esm src/scripts/copy_output.ts zk_token", | ||
"noir:build:pub_token": "(cd src/contracts/public_token_contract && nargo compile main --contracts) && ts-node --esm src/scripts/copy_output.ts public_token" | ||
"noir:build:pub_token": "(cd src/contracts/public_token_contract && nargo compile main --contracts) && ts-node --esm src/scripts/copy_output.ts public_token", | ||
"noir:build:l1_token": "(cd src/contracts/non_native_token_contract && nargo compile main --contracts) && ts-node --esm src/scripts/copy_output.ts non_native_token" |
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.
Think you run into size limits.
|
||
// TODO: Still need to check that the secret hash -> note hash | ||
// this should be another pedersen generator ? | ||
global L1_MESSAGE_LEN = 8; |
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.
For consistency, think it would be nice if it is referred to as L1_TO_L2
, generally for this file some places it is L1Message but and other L1ToL2.
} | ||
|
||
fn compute_msg_hash(_self: Self) -> Field { | ||
// Todo a sha256 hash of the message |
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.
Is there an issue for this 👀?
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.
Implementing in current interation
Description
part of #522, #515
Overview
Adds a series of functionality to the acvm as well as a noir contract that can consume an l1 to l2 message and create a nullifier for it.
TokenPortal
that is capable of holding assets and sending messages instructing tokens to be minted on the L2.msgKey
, and returns key information to the noir context, essentially the same info that is included within the solidity structNotes
const p = prime_order
from typescript and replaces it with the static fieldFr.MODULO
which is the samePlease provide a paragraph or two giving a summary of the change, including relevant motivation and context.
Checklist: