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.
wdym? does this have an issue we are tracking it in?
There was a problem hiding this comment.
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.
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.
why do you have 2 IInbox interfaces?
There was a problem hiding this comment.
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.
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.
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.
have you flagged this issue somewhere?
There was a problem hiding this comment.
Ah I have not, but it is a known issue, #611 made this for tracking
There was a problem hiding this comment.
If you put the issue in the comment would be neat 👍
| private writeInputs() { | ||
| const argsSize = this.abi.parameters.reduce((acc, param) => acc + sizeOfType(param.type), 0); | ||
|
|
||
| console.log('storage contract address: ', this.callContext.storageContractAddress); |
| global NoteStorageSlot = 3; | ||
| global MappingStorageSlot = 4; | ||
| global Nullifier = 5; | ||
| global L1ToL2MessageSecret = 29; |
There was a problem hiding this comment.
I am out of the loop - why is this 29? is this the pedereson generator constant?
There was a problem hiding this comment.
Its index 29 here:
| 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.
damn is this how we create private vars in noir now?
There was a problem hiding this comment.
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.
question so I understand this better -> how does this work?
There was a problem hiding this comment.
In the acvm you can register callbacks:
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]; |
LHerskind
left a comment
There was a problem hiding this comment.
A bit inconsistenct on L1 or L1ToL2 naming, but nice job 👍
| "@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.
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?
| import {MockVerifier} from "@aztec/mock/MockVerifier.sol"; | ||
| import {Decoder} from "./Decoder.sol"; | ||
|
|
||
| // Messaging |
There was a problem hiding this comment.
Think this needs a rebase to get the updates from #609
| pragma solidity >=0.8.18; | ||
|
|
||
| library DataStructures { | ||
| // Prime field modulus |
There was a problem hiding this comment.
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.
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.
| * @param msgKey - A buffer representing the message key. | ||
| * @returns The message data | ||
| */ | ||
| public async getL1ToL2Message(msgKey: Fr) { |
There was a problem hiding this comment.
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.
Why do you want max uint - 1? The maxuint is already 2**32 - 1
| "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.
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.
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.
Is there an issue for this 👀?
There was a problem hiding this comment.
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.
TokenPortalthat 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_orderfrom typescript and replaces it with the static fieldFr.MODULOwhich is the samePlease provide a paragraph or two giving a summary of the change, including relevant motivation and context.
Checklist: