Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 52 additions & 1 deletion yarn-project/end-to-end/src/cross_chain/test_harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { AztecAddress, EthAddress, Fr, Point } from '@aztec/circuits.js';
import { DeployL1Contracts } from '@aztec/ethereum';
import { DebugLogger } from '@aztec/foundation/log';
import { PublicClient, HttpTransport, Chain, getContract } from 'viem';
import { deployAndInitializeNonNativeL2TokenContracts, pointToPublicKey } from '../utils.js';
import { deployAndInitializeNonNativeL2TokenContracts, expectStorageSlot, pointToPublicKey } from '../utils.js';
import { OutboxAbi } from '@aztec/l1-artifacts';
import { sha256ToField } from '@aztec/foundation/crypto';
import { toBufferBE } from '@aztec/foundation/bigint-buffer';
Expand Down Expand Up @@ -120,6 +120,10 @@ export class CrossChainTestHarness {
expect(await this.underlyingERC20.read.balanceOf([this.ethAccount.toString()])).toBe(amount);
}

async getL1BalanceOf(address: EthAddress) {
return await this.underlyingERC20.read.balanceOf([address.toString()]);
}

async sendTokensToPortal(bridgeAmount: bigint, secretHash: Fr) {
await this.underlyingERC20.write.approve([this.tokenPortalAddress.toString(), bridgeAmount], {} as any);

Expand Down Expand Up @@ -158,6 +162,53 @@ export class CrossChainTestHarness {
expect(transferReceipt.status).toBe(TxStatus.MINED);
}

async consumeMessageOnAztecAndMintSecretly(bridgeAmount: bigint, messageKey: Fr, secret: Fr) {
this.logger('Consuming messages on L2 secretively');
// Call the mint tokens function on the noir contract
const consumptionTx = this.l2Contract.methods
.mint(bridgeAmount, this.ownerPub, this.ownerAddress, messageKey, secret, this.ethAccount.toField())
.send({ from: this.ownerAddress });

await consumptionTx.isMined(0, 0.1);
const consumptionReceipt = await consumptionTx.getReceipt();
expect(consumptionReceipt.status).toBe(TxStatus.MINED);
}

async consumeMessageOnAztecAndMintPublicly(bridgeAmount: bigint, messageKey: Fr, secret: Fr) {
this.logger('Consuming messages on L2 Publicly');
// Call the mint tokens function on the noir contract
const consumptionTx = this.l2Contract.methods
.mintPublic(bridgeAmount, this.ownerAddress, messageKey, secret, this.ethAccount.toField())
.send({ from: this.ownerAddress });

await consumptionTx.isMined(0, 0.1);
const consumptionReceipt = await consumptionTx.getReceipt();
expect(consumptionReceipt.status).toBe(TxStatus.MINED);
}

async getL2BalanceOf(owner: AztecAddress) {
const ownerPublicKey = await this.aztecRpcServer.getAccountPublicKey(owner);
const [balance] = await this.l2Contract.methods.getBalance(pointToPublicKey(ownerPublicKey)).view({ from: owner });
return balance;
}

async expectBalanceOnL2(owner: AztecAddress, expectedBalance: bigint) {
const balance = await this.getL2BalanceOf(owner);
this.logger(`Account ${owner} balance: ${balance}`);
expect(balance).toBe(expectedBalance);
}

async expectPublicBalanceOnL2(owner: AztecAddress, expectedBalance: bigint, publicBalanceSlot: bigint) {
await expectStorageSlot(
this.logger,
this.aztecNode,
this.l2Contract,
publicBalanceSlot,
owner.toField(),
expectedBalance,
);
}

async checkEntryIsNotInOutbox(withdrawAmount: bigint, callerOnL1: EthAddress = EthAddress.ZERO): Promise<Fr> {
this.logger('Ensure that the entry is not in outbox yet');
const contractInfo = await this.aztecNode.getContractInfo(this.l2Contract.address);
Expand Down
17 changes: 2 additions & 15 deletions yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AztecNodeService } from '@aztec/aztec-node';
import { AztecAddress, AztecRPCServer, Contract, TxStatus } from '@aztec/aztec.js';
import { EthAddress } from '@aztec/foundation/eth-address';

import { Fr, Point } from '@aztec/foundation/fields';
import { Point } from '@aztec/foundation/fields';
import { DebugLogger } from '@aztec/foundation/log';
import { delay, pointToPublicKey, setup } from './utils.js';
import { CrossChainTestHarness } from './cross_chain/test_harness.js';
Expand Down Expand Up @@ -65,19 +65,6 @@ describe('e2e_cross_chain_messaging', () => {
expect(balance).toBe(expectedBalance);
};

const consumeMessageOnAztecAndMint = async (bridgeAmount: bigint, messageKey: Fr, secret: Fr) => {
logger('Consuming messages on L2 secretively');
// Call the mint tokens function on the noir contract
const consumptionTx = l2Contract.methods
.mint(bridgeAmount, ownerPub, ownerAddress, messageKey, secret, ethAccount.toField())
.send({ from: ownerAddress });

await consumptionTx.isMined(0, 0.1);
const consumptionReceipt = await consumptionTx.getReceipt();

expect(consumptionReceipt.status).toBe(TxStatus.MINED);
};

const withdrawFundsFromAztec = async (withdrawAmount: bigint) => {
logger('Send L2 tx to withdraw funds');
const withdrawTx = l2Contract.methods
Expand Down Expand Up @@ -108,7 +95,7 @@ describe('e2e_cross_chain_messaging', () => {
const transferAmount = 1n;
await crossChainTestHarness.performL2Transfer(transferAmount);

await consumeMessageOnAztecAndMint(bridgeAmount, messageKey, secret);
await crossChainTestHarness.consumeMessageOnAztecAndMintSecretly(bridgeAmount, messageKey, secret);
await expectBalance(ownerAddress, bridgeAmount + initialBalance - transferAmount);

// time to withdraw the funds again!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { AztecNodeService } from '@aztec/aztec-node';
import { AztecAddress, AztecRPCServer, Contract, TxStatus } from '@aztec/aztec.js';
import { EthAddress } from '@aztec/foundation/eth-address';

import { Fr } from '@aztec/foundation/fields';
import { DebugLogger } from '@aztec/foundation/log';
import { delay, expectStorageSlot, setup } from './utils.js';
import { delay, setup } from './utils.js';
import { CrossChainTestHarness } from './cross_chain/test_harness.js';

describe('e2e_public_cross_chain_messaging', () => {
Expand Down Expand Up @@ -58,19 +57,6 @@ describe('e2e_public_cross_chain_messaging', () => {
await crossChainTestHarness?.stop();
});

const consumeMessageOnAztec = async (bridgeAmount: bigint, messageKey: Fr, secret: Fr) => {
logger('Consuming messages on L2 Publicly');
// Call the mint tokens function on the noir contract
const consumptionTx = l2Contract.methods
.mintPublic(bridgeAmount, ownerAddress, messageKey, secret, ethAccount.toField())
.send({ from: ownerAddress });

await consumptionTx.isMined(0, 0.1);
const consumptionReceipt = await consumptionTx.getReceipt();

expect(consumptionReceipt.status).toBe(TxStatus.MINED);
};

const withdrawFundsFromAztec = async (withdrawAmount: bigint) => {
logger('Send L2 tx to withdraw funds');
const withdrawTx = l2Contract.methods
Expand Down Expand Up @@ -102,22 +88,15 @@ describe('e2e_public_cross_chain_messaging', () => {
const transferAmount = 1n;
await crossChainTestHarness.performL2Transfer(transferAmount);

await consumeMessageOnAztec(bridgeAmount, messageKey, secret);
await expectStorageSlot(logger, aztecNode, l2Contract, publicBalanceSlot, ownerAddress.toField(), bridgeAmount);
await crossChainTestHarness.consumeMessageOnAztecAndMintPublicly(bridgeAmount, messageKey, secret);
await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount, publicBalanceSlot);

// time to withdraw the funds again!
logger('Withdrawing funds from L2');
const withdrawAmount = 9n;
const entryKey = await crossChainTestHarness.checkEntryIsNotInOutbox(withdrawAmount);
await withdrawFundsFromAztec(withdrawAmount);
await expectStorageSlot(
logger,
aztecNode,
l2Contract,
publicBalanceSlot,
ownerAddress.toField(),
bridgeAmount - withdrawAmount,
);
await crossChainTestHarness.expectPublicBalanceOnL2(ownerAddress, bridgeAmount - withdrawAmount, publicBalanceSlot);

// Check balance before and after exit.
expect(await underlyingERC20.read.balanceOf([ethAccount.toString()])).toBe(l1TokenBalance - bridgeAmount);
Expand Down
Loading