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

Bridging layer 2 native asset to L1 #552

Merged
merged 15 commits into from
May 18, 2023
Merged

Bridging layer 2 native asset to L1 #552

merged 15 commits into from
May 18, 2023

Conversation

LHerskind
Copy link
Contributor

@LHerskind LHerskind commented May 12, 2023

Description

Working on #518, #519 towards #514

Please provide a paragraph or two giving a summary of the change, including relevant motivation and context.

Checklist:

  • I have reviewed my diff in github, line by line.
  • Every change is related to the PR description.
  • I have linked this pull request to the issue(s) that it resolves.
  • There are no unexpected formatting changes, superfluous debug logs, or commented-out code.
  • The branch has been merged or rebased against the head of its merge target.
  • I'm happy for the PR to be merged at the reviewer's next convenience.

@LHerskind LHerskind force-pushed the lh/l2-native-asset branch from 003ca53 to 83540ec Compare May 16, 2023 10:00
@LHerskind LHerskind force-pushed the lh/l2-native-asset branch from 5e082f6 to 571606c Compare May 17, 2023 20:45
@LHerskind LHerskind changed the title Bridging layer 2 native asset bridging to L1 Bridging layer 2 native asset to L1 May 17, 2023
@LHerskind LHerskind marked this pull request as ready for review May 17, 2023 21:32
} else {
// @todo @LHerskind chain-ids and rollup version id should be added here. Right now, just hard coded.
new_l2_to_l1_msgs_to_insert[i] = compute_l2_to_l1_hash<NT>(storage_contract_address,
fr(1), // rollup version id
Copy link
Member

Choose a reason for hiding this comment

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

should chainid and rollup version be global in constants.hpp

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The rollup version should depend on the version of the rollup so should probably be in context or something, @iAmMichaelConnor we probably should talk to figure out where we should get this from.

Similarly, chainid should be from context. So again, lets talk to @iAmMichaelConnor.


auto offset = i * 32;
std::copy(as_bytes.begin(), as_bytes.end(), calldata_hash_inputs_bytes.begin() + offset);
}
Copy link
Member

Choose a reason for hiding this comment

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

Is the point of this to pad all the values to 32 bytes? if theyre all already field elements of the same type would just copying it to the uint8 array in one go not be sufficient. Genuinely curious not sure if you can do it

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 don't recall why it was done like this, think I just took what we had in the components 😅, so both might need an update.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if this is relevant to the topic raised Sean, but we would still need to still pad them to 32 bytes each. In solidity, before hashing, both L1Actor abd L2Actor is 64 bytes each (since they have 2 fields each) after doing abi.encode

Copy link
Member

Choose a reason for hiding this comment

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

Ok, I've made a draft issue in a3 faries to refactor this

registry.setAddresses(address(rollup), address(inbox), address(outbox));

rna = new RollupNativeAsset();
vm.etch(address(0xbeef), address(rna).code);
Copy link
Member

Choose a reason for hiding this comment

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

guessing this is hardcoded for the entry key calculation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ye, this was just to match what was generated from the typescript, etching to make it a bit easier to match.

Copy link
Contributor

Choose a reason for hiding this comment

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

can you add a comment on why the etch?

import {Registry} from "@aztec/core/messagebridge/Registry.sol";

contract RollupNativeAsset is ERC20 {
uint256 public constant P =
Copy link
Member

Choose a reason for hiding this comment

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

Proposal to make P a constant of DataStructures or the likes (ive done so here on an awaiting pr)

uint256 constant P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, lets make a Constants.sol in there as well. Thinking if it also made sense to look at doing a library for errors, if full library is included in ABI generation, should provide more meaningful errors when simulating tx's in viem 🤔


const sha256ToField = (buf: Buffer): Fr => {
// Prime order of BN254 curve
const p = BigInt('21888242871839275222246405745257275088548364400416034343698204186575808495617');
Copy link
Member

Choose a reason for hiding this comment

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

Use Fr.MODULUS instead, its available as a static val

let accounts: AztecAddress[];
let contract: Contract;
let portalAddress: EthAddress;
let portalContract: any; //<typeof RollupNativeAssetAbi, PublicClient<HttpTransport, Chain>>;
Copy link
Member

Choose a reason for hiding this comment

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

gotta love viem

expect(balance).toBe(expectedBalance);
};

const pointToPublicKey = (point: Point) => {
Copy link
Member

Choose a reason for hiding this comment

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

This is used alot right? Should we make a helper function for it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will probably be useful to take this and a few other of the widely used End-To-End functions and move it into some utilities.

// }
// }
{
const auto& portal_contract_address = private_inputs.private_call.portal_contract_address;
Copy link
Member

Choose a reason for hiding this comment

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

Can a copy of this line commented out a few lines above be removed now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, ye will get rid of it.

@AztecProtocol AztecProtocol deleted a comment from LHerskind May 18, 2023

auto offset = i * 32;
std::copy(as_bytes.begin(), as_bytes.end(), calldata_hash_inputs_bytes.begin() + offset);
}
Copy link
Member

Choose a reason for hiding this comment

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

Ok, I've made a draft issue in a3 faries to refactor this

const auto& new_l2_to_l1_msgs = private_call_public_inputs.new_l2_to_l1_msgs;
std::array<NT::fr, NEW_L2_TO_L1_MSGS_LENGTH> new_l2_to_l1_msgs_to_insert;
for (size_t i = 0; i < new_l2_to_l1_msgs.size(); ++i) {
if (new_l2_to_l1_msgs[i] == 0) {
Copy link
Member

Choose a reason for hiding this comment

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

You can call .is_zero() on fields

std::array<NT::fr, NEW_L2_TO_L1_MSGS_LENGTH> new_l2_to_l1_msgs_to_insert;
for (size_t i = 0; i < new_l2_to_l1_msgs.size(); ++i) {
if (new_l2_to_l1_msgs[i] == 0) {
new_l2_to_l1_msgs_to_insert[i] = 0;
Copy link
Member

Choose a reason for hiding this comment

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

nit: similarly defining this to fr.zero is more expressive


auto offset = i * 32;
std::copy(as_bytes.begin(), as_bytes.end(), calldata_hash_inputs_bytes.begin() + offset);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if this is relevant to the topic raised Sean, but we would still need to still pad them to 32 bytes each. In solidity, before hashing, both L1Actor abd L2Actor is 64 bytes each (since they have 2 fields each) after doing abi.encode

registry.setAddresses(address(rollup), address(inbox), address(outbox));

rna = new RollupNativeAsset();
vm.etch(address(0xbeef), address(rna).code);
Copy link
Contributor

Choose a reason for hiding this comment

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

can you add a comment on why the etch?

outbox.sendL1Messages(entryKeys);

assertEq(rna.balanceOf(address(0xdead)), 0);
bytes32 entryKey = rna.withdraw(654, address(0xdead));
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: also check that MessageConsumed event was fired

} from 'viem';
import { foundry } from 'viem/chains';

const MNEMONIC = 'test test test test test test test test test test test junk';
Copy link
Contributor

Choose a reason for hiding this comment

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

to avoid a merge conflict with Sean's work, you can create a fixture.ts and import MNEMONIC from there! Ref

Copy link
Member

Choose a reason for hiding this comment

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

its all good im ok with refactoring it when i merge master

};
};

const deployContract = async (initialBalance = 0n, owner = { x: 0n, y: 0n }) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

rename to deployNativeTokenContract. deployContract() is a bit vague (esp since this exact fn name is used across other E2Es too as far as I remember)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its the same thing across the E2Es, part of what is referred to in #552 (comment)

await deployContract(initialBalance, pointToPublicKey(await aztecRpcServer.getAccountPublicKey(owner)));
await expectBalance(owner, initialBalance);

const { request: initRequest } = await publicClient.simulateContract({
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we need to simulate contract? Is this ACVM stuff (which simulates before creating the kernel proof? For whatever reason I assumed this would be abstracted away)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is viem simulating the call and then executing it.


const blockNumber = await node.getBlockHeight();
const blocks = await node.getBlocks(blockNumber, 1);
// If this is failing, it is likely because of wrong chain id
Copy link
Contributor

Choose a reason for hiding this comment

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

how do you set the right chain id?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mainly that the two domains need to match, e.g., rollup and l1 need to specify the same chainid for messages to hit the expected hashes, if one use 1 and other use 31337 you won't find occurences of the messages correctly.

@@ -0,0 +1,51 @@
use dep::aztec3::notes::value_note::Note;
Copy link
Contributor

Choose a reason for hiding this comment

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

For my understanding - whats the point of this file? Is all of this just syntactic sugar?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its an implementation to getcompute the balance of a user.

@LHerskind LHerskind mentioned this pull request May 18, 2023
6 tasks
Copy link
Contributor

@rahul-kothari rahul-kothari left a comment

Choose a reason for hiding this comment

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

amazing stuff!

@Maddiaa0 Maddiaa0 merged commit ddd3abd into master May 18, 2023
@Maddiaa0 Maddiaa0 deleted the lh/l2-native-asset branch May 18, 2023 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Token bridge portal contract (l2 native asset) acir simulator to emit L2 -> L1 messages
3 participants