Skip to content

Commit

Permalink
Merge branch 'master' into janb/multiple-rpc-servers-1-node
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Oct 3, 2023
2 parents ce0478f + 10b30e0 commit 04d06ae
Show file tree
Hide file tree
Showing 30 changed files with 222 additions and 178 deletions.
4 changes: 3 additions & 1 deletion circuits/cpp/src/aztec3/circuits/kernel/public/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ void common_initialise_end_values(PublicKernelInputs<NT> const& public_kernel_in
// Public kernel does not modify encrypted logs values --> we just copy them to output
end.encrypted_logs_hash = start.encrypted_logs_hash;
end.encrypted_log_preimages_length = start.encrypted_log_preimages_length;

end.new_contracts = start.new_contracts;
}

/**
Expand Down Expand Up @@ -70,4 +72,4 @@ void validate_this_public_call_hash(DummyBuilder& builder,
") at the top of the call stack"),
CircuitErrorCode::PUBLIC_KERNEL__CALCULATED_PUBLIC_CALL_HASH_AND_PROVIDED_PUBLIC_CALL_HASH_MISMATCH);
};
} // namespace aztec3::circuits::kernel::public_kernel
} // namespace aztec3::circuits::kernel::public_kernel
2 changes: 1 addition & 1 deletion docs/docs/dev_docs/tutorials/writing_token_contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ Internal functions are functions that can only be called by this contract. The f

#### `_initialize`

This function is called via the [constructor](#constructor). Note that it is not actually marked `internal` right now--this is because this functionality is still being worked on.
This function is called via the [constructor](#constructor).

This function sets the creator of the contract (passed as `msg_sender` from the constructor) as the admin and makes them a minter.

Expand Down
27 changes: 7 additions & 20 deletions yarn-project/canary/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,40 +66,27 @@ export async function deployAndInitializeTokenAndBridgeContracts(
});

// deploy l2 token
const deployTx = TokenContract.deploy(wallet).send();

// deploy l2 token bridge and attach to the portal
const bridgeTx = TokenBridgeContract.deploy(wallet).send({
portalContract: tokenPortalAddress,
contractAddressSalt: Fr.random(),
});
const deployTx = TokenContract.deploy(wallet, owner).send();

// now wait for the deploy txs to be mined. This way we send all tx in the same rollup.
const deployReceipt = await deployTx.wait();
if (deployReceipt.status !== TxStatus.MINED) throw new Error(`Deploy token tx status is ${deployReceipt.status}`);
const token = await TokenContract.at(deployReceipt.contractAddress!, wallet);

// deploy l2 token bridge and attach to the portal
const bridgeTx = TokenBridgeContract.deploy(wallet, token.address).send({
portalContract: tokenPortalAddress,
contractAddressSalt: Fr.random(),
});

const bridgeReceipt = await bridgeTx.wait();
if (bridgeReceipt.status !== TxStatus.MINED) throw new Error(`Deploy bridge tx status is ${bridgeReceipt.status}`);
const bridge = await TokenBridgeContract.at(bridgeReceipt.contractAddress!, wallet);
await bridge.attach(tokenPortalAddress);
const bridgeAddress = bridge.address.toString() as `0x${string}`;

// initialize l2 token
const initializeTx = token.methods._initialize(owner).send();

// initialize bridge
const initializeBridgeTx = bridge.methods._initialize(token.address).send();

// now we wait for the txs to be mined. This way we send all tx in the same rollup.
const initializeReceipt = await initializeTx.wait();
if (initializeReceipt.status !== TxStatus.MINED)
throw new Error(`Initialize token tx status is ${initializeReceipt.status}`);
if ((await token.methods.admin().view()) !== owner.toBigInt()) throw new Error(`Token admin is not ${owner}`);

const initializeBridgeReceipt = await initializeBridgeTx.wait();
if (initializeBridgeReceipt.status !== TxStatus.MINED)
throw new Error(`Initialize token bridge tx status is ${initializeBridgeReceipt.status}`);
if ((await bridge.methods.token().view()) !== token.address.toBigInt())
throw new Error(`Bridge token is not ${token.address}`);

Expand Down
5 changes: 3 additions & 2 deletions yarn-project/end-to-end/src/canary/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,14 @@ export const browserTestSuite = (setup: () => Server, pageLogger: AztecJs.DebugL
}
const [owner] = await getSandboxAccountsWallets(pxe);
const ownerAddress = owner.getAddress();
const tx = new DeployMethod(accounts[0].publicKey, pxe, TokenContractAbi).send();
const tx = new DeployMethod(accounts[0].publicKey, pxe, TokenContractAbi, [
owner.getCompleteAddress(),
]).send();
await tx.wait();
const receipt = await tx.getReceipt();
console.log(`Contract Deployed: ${receipt.contractAddress}`);

const token = await Contract.at(receipt.contractAddress!, TokenContractAbi, owner);
await token.methods._initialize(ownerAddress).send().wait();
const secret = Fr.random();
const secretHash = await computeMessageSecretHash(secret);
const mintPrivateReceipt = await token.methods.mint_private(initialBalance, secretHash).send().wait();
Expand Down
7 changes: 1 addition & 6 deletions yarn-project/end-to-end/src/canary/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export const cliTestSuite = (
const ownerAddress = AztecAddress.fromString(foundAddress!);

debug('Deploy Token Contract using created account.');
await run(`deploy TokenContractAbi --salt 0`);
await run(`deploy TokenContractAbi --salt 0 --args ${ownerAddress}`);
const loggedAddress = findInLogs(/Contract\sdeployed\sat\s+(?<address>0x[a-fA-F0-9]+)/)?.groups?.address;
expect(loggedAddress).toBeDefined();
contractAddress = AztecAddress.fromString(loggedAddress!);
Expand All @@ -131,11 +131,6 @@ export const cliTestSuite = (
const checkResult = findInLogs(/Contract\sfound\sat\s+(?<address>0x[a-fA-F0-9]+)/)?.groups?.address;
expect(checkResult).toEqual(deployedContract?.contractAddress.toString());

debug('Initialize token contract.');
await run(
`send _initialize --args ${ownerAddress} --contract-abi TokenContractAbi --contract-address ${contractAddress.toString()} --private-key ${privKey}`,
);

const secret = Fr.random();
const secretHash = await computeMessageSecretHash(secret);

Expand Down
3 changes: 1 addition & 2 deletions yarn-project/end-to-end/src/e2e_2_pxes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ describe('e2e_2_pxes', () => {

const deployTokenContract = async (initialAdminBalance: bigint, admin: AztecAddress, pxe: PXE) => {
logger(`Deploying Token contract...`);
const contract = await TokenContract.deploy(walletA).send().deployed();
expect((await contract.methods._initialize(admin).send().wait()).status).toBe(TxStatus.MINED);
const contract = await TokenContract.deploy(walletA, admin).send().deployed();

if (initialAdminBalance > 0n) {
await mintTokens(contract, admin, initialAdminBalance, pxe);
Expand Down
59 changes: 51 additions & 8 deletions yarn-project/end-to-end/src/e2e_block_building.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { BatchCall, ContractDeployer, Fr, Wallet, isContractDeployed } from '@aztec/aztec.js';
import {
BatchCall,
ContractDeployer,
ContractFunctionInteraction,
Fr,
Wallet,
isContractDeployed,
} from '@aztec/aztec.js';
import { CircuitsWasm } from '@aztec/circuits.js';
import { pedersenPlookupCommitInputs } from '@aztec/circuits.js/barretenberg';
import { DebugLogger } from '@aztec/foundation/log';
import { TestContractAbi } from '@aztec/noir-contracts/artifacts';
import { TestContract } from '@aztec/noir-contracts/types';
import { TestContract, TokenContract } from '@aztec/noir-contracts/types';
import { PXE, TxStatus } from '@aztec/types';

import times from 'lodash.times';
Expand All @@ -13,14 +20,20 @@ import { setup } from './fixtures/utils.js';
describe('e2e_block_building', () => {
let pxe: PXE;
let logger: DebugLogger;
let wallet: Wallet;
let owner: Wallet;
let minter: Wallet;
let teardown: () => Promise<void>;

describe('multi-txs block', () => {
const abi = TestContractAbi;

beforeAll(async () => {
({ teardown, pxe, logger, wallet } = await setup(1));
({
teardown,
pxe,
logger,
wallets: [owner, minter],
} = await setup(2));
}, 100_000);

afterAll(() => teardown());
Expand All @@ -29,7 +42,7 @@ describe('e2e_block_building', () => {
// Assemble N contract deployment txs
// We need to create them sequentially since we cannot have parallel calls to a circuit
const TX_COUNT = 8;
const deployer = new ContractDeployer(abi, wallet);
const deployer = new ContractDeployer(abi, owner);
const methods = times(TX_COUNT, () => deployer.deploy());

for (const i in methods) {
Expand All @@ -51,6 +64,36 @@ describe('e2e_block_building', () => {
const areDeployed = await Promise.all(receipts.map(r => isContractDeployed(pxe, r.contractAddress!)));
expect(areDeployed).toEqual(times(TX_COUNT, () => true));
}, 60_000);

it('can call public function from different tx in same block', async () => {
// Deploy a contract in the first transaction
// In the same block, call a public method on the contract
const deployer = TokenContract.deploy(owner, owner.getCompleteAddress());
await deployer.create();

// We can't use `TokenContract.at` to call a function because it checks the contract is deployed
// but we are in the same block as the deployment transaction
const callInteraction = new ContractFunctionInteraction(
owner,
deployer.completeAddress!.address,
TokenContract.abi.functions.find(x => x.name === 'set_minter')!,
[minter.getCompleteAddress(), true],
);

await deployer.simulate({});
await callInteraction.simulate({
// we have to skip simulation of public calls simulation is done on individual transactions
// and the tx deploying the contract might go in the same block as this one
skipPublicSimulation: true,
});

const [deployTxReceipt, callTxReceipt] = await Promise.all([
deployer.send().wait(),
callInteraction.send({ skipPublicSimulation: true }).wait(),
]);

expect(deployTxReceipt.blockNumber).toEqual(callTxReceipt.blockNumber);
}, 60_000);
});

// Regressions for https://github.com/AztecProtocol/aztec-packages/issues/2502
Expand All @@ -59,8 +102,8 @@ describe('e2e_block_building', () => {
let teardown: () => Promise<void>;

beforeAll(async () => {
({ teardown, pxe, logger, wallet } = await setup(1));
contract = await TestContract.deploy(wallet).send().deployed();
({ teardown, pxe, logger, wallet: owner } = await setup(1));
contract = await TestContract.deploy(owner).send().deployed();
}, 100_000);

afterAll(() => teardown());
Expand All @@ -86,7 +129,7 @@ describe('e2e_block_building', () => {
it('drops tx with two equal nullifiers', async () => {
const nullifier = Fr.random();
const calls = times(2, () => contract.methods.emit_nullifier(nullifier).request());
await expect(new BatchCall(wallet, calls).send().wait()).rejects.toThrowError(/dropped/);
await expect(new BatchCall(owner, calls).send().wait()).rejects.toThrowError(/dropped/);
});

it('drops tx with private nullifier already emitted from public on the same block', async () => {
Expand Down
4 changes: 1 addition & 3 deletions yarn-project/end-to-end/src/e2e_escrow_contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ describe('e2e_escrow_contract', () => {
logger(`Escrow contract deployed at ${escrowContract.address}`);

// Deploy Private Token contract and mint funds for the escrow contract
token = await TokenContract.deploy(wallet).send().deployed();

expect((await token.methods._initialize(owner).send().wait()).status).toBe(TxStatus.MINED);
token = await TokenContract.deploy(wallet, owner).send().deployed();

const mintAmount = 100n;
const secret = Fr.random();
Expand Down
6 changes: 2 additions & 4 deletions yarn-project/end-to-end/src/e2e_lending_contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ describe('e2e_lending_contract', () => {

{
logger(`Deploying collateral asset feed contract...`);
const receipt = await waitForSuccess(TokenContract.deploy(wallet).send());
const receipt = await waitForSuccess(TokenContract.deploy(wallet, accounts[0]).send());
logger(`Collateral asset deployed to ${receipt.contractAddress}`);
collateralAsset = await TokenContract.at(receipt.contractAddress!, wallet);
}

{
logger(`Deploying stable coin contract...`);
const receipt = await waitForSuccess(TokenContract.deploy(wallet).send());
const receipt = await waitForSuccess(TokenContract.deploy(wallet, accounts[0]).send());
logger(`Stable coin asset deployed to ${receipt.contractAddress}`);
stableCoin = await TokenContract.at(receipt.contractAddress!, wallet);
}
Expand All @@ -69,9 +69,7 @@ describe('e2e_lending_contract', () => {
lendingContract = await LendingContract.at(receipt.contractAddress!, wallet);
}

await waitForSuccess(collateralAsset.methods._initialize(accounts[0]).send());
await waitForSuccess(collateralAsset.methods.set_minter(lendingContract.address, true).send());
await waitForSuccess(stableCoin.methods._initialize(accounts[0]).send());
await waitForSuccess(stableCoin.methods.set_minter(lendingContract.address, true).send());

return { priceFeedContract, lendingContract, collateralAsset, stableCoin };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,10 @@ describe('e2e_multiple_accounts_1_enc_key', () => {
}

logger(`Deploying Token...`);
const token = await TokenContract.deploy(wallets[0]).send().deployed();
const token = await TokenContract.deploy(wallets[0], accounts[0]).send().deployed();
tokenAddress = token.address;
logger(`Token deployed at ${tokenAddress}`);

expect((await token.methods._initialize(accounts[0]).send().wait()).status).toBe(TxStatus.MINED);

const secret = Fr.random();
const secretHash = await computeMessageSecretHash(secret);

Expand Down
5 changes: 2 additions & 3 deletions yarn-project/end-to-end/src/e2e_sandbox_example.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,12 @@ describe('e2e_sandbox_example', () => {
const initialSupply = 1_000_000n;

logger(`Deploying token contract minting an initial ${initialSupply} tokens to Alice...`);
const contract = await TokenContract.deploy(pxe).send().deployed();
const contract = await TokenContract.deploy(pxe, alice).send().deployed();

// Create the contract abstraction and link to Alice's wallet for future signing
const tokenContractAlice = await TokenContract.at(contract.address, accounts[0]);

// Initialize the contract and add Bob as a minter
await tokenContractAlice.methods._initialize(alice).send().wait();
// add Bob as a minter
await tokenContractAlice.methods.set_minter(bob, true).send().wait();

logger(`Contract successfully deployed at address ${contract.address.toShortString()}`);
Expand Down
3 changes: 1 addition & 2 deletions yarn-project/end-to-end/src/e2e_token_contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,14 @@ describe('e2e_token_contract', () => {
beforeAll(async () => {
({ teardown, logger, wallets, accounts } = await setup(3));

asset = await TokenContract.deploy(wallets[0]).send().deployed();
asset = await TokenContract.deploy(wallets[0], accounts[0]).send().deployed();
logger(`Token deployed to ${asset.address}`);
tokenSim = new TokenSimulator(
asset,
logger,
accounts.map(a => a.address),
);

await asset.methods._initialize(accounts[0].address).send().wait();
expect(await asset.methods.admin().view()).toBe(accounts[0].address.toBigInt());

asset.abi.functions.forEach(fn => {
Expand Down
26 changes: 6 additions & 20 deletions yarn-project/end-to-end/src/fixtures/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,40 +409,26 @@ export async function deployAndInitializeTokenAndBridgeContracts(
});

// deploy l2 token
const deployTx = TokenContract.deploy(wallet).send();

// deploy l2 token bridge and attach to the portal
const bridgeTx = TokenBridgeContract.deploy(wallet).send({
portalContract: tokenPortalAddress,
contractAddressSalt: Fr.random(),
});
const deployTx = TokenContract.deploy(wallet, owner).send();

// now wait for the deploy txs to be mined. This way we send all tx in the same rollup.
const deployReceipt = await deployTx.wait();
if (deployReceipt.status !== TxStatus.MINED) throw new Error(`Deploy token tx status is ${deployReceipt.status}`);
const token = await TokenContract.at(deployReceipt.contractAddress!, wallet);

// deploy l2 token bridge and attach to the portal
const bridgeTx = TokenBridgeContract.deploy(wallet, token.address).send({
portalContract: tokenPortalAddress,
contractAddressSalt: Fr.random(),
});
const bridgeReceipt = await bridgeTx.wait();
if (bridgeReceipt.status !== TxStatus.MINED) throw new Error(`Deploy bridge tx status is ${bridgeReceipt.status}`);
const bridge = await TokenBridgeContract.at(bridgeReceipt.contractAddress!, wallet);
await bridge.attach(tokenPortalAddress);
const bridgeAddress = bridge.address.toString() as `0x${string}`;

// initialize l2 token
const initializeTx = token.methods._initialize(owner).send();

// initialize bridge
const initializeBridgeTx = bridge.methods._initialize(token.address).send();

// now we wait for the txs to be mined. This way we send all tx in the same rollup.
const initializeReceipt = await initializeTx.wait();
if (initializeReceipt.status !== TxStatus.MINED)
throw new Error(`Initialize token tx status is ${initializeReceipt.status}`);
if ((await token.methods.admin().view()) !== owner.toBigInt()) throw new Error(`Token admin is not ${owner}`);

const initializeBridgeReceipt = await initializeBridgeTx.wait();
if (initializeBridgeReceipt.status !== TxStatus.MINED)
throw new Error(`Initialize token bridge tx status is ${initializeBridgeReceipt.status}`);
if ((await bridge.methods.token().view()) !== token.address.toBigInt())
throw new Error(`Bridge token is not ${token.address}`);

Expand Down
Loading

0 comments on commit 04d06ae

Please sign in to comment.