Skip to content

Commit

Permalink
refactor: add gas portal to l1 contract addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
alexghr committed Mar 18, 2024
1 parent e146076 commit 2b2e931
Show file tree
Hide file tree
Showing 17 changed files with 163 additions and 82 deletions.
9 changes: 4 additions & 5 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ setup_env: &setup_env
command: ./build-system/scripts/setup_env "$CIRCLE_SHA1" "$CIRCLE_TAG" "$CIRCLE_JOB" "$CIRCLE_REPOSITORY_URL" "$CIRCLE_BRANCH" "$CIRCLE_PULL_REQUEST"

defaults_e2e_test: &defaults_e2e_test
docker:
- image: aztecprotocol/alpine-build-image
resource_class: small
docker:
- image: aztecprotocol/alpine-build-image
resource_class: small

jobs:
# Dynamically filter our code, quickly figuring out which jobs we can skip.
Expand Down Expand Up @@ -868,7 +868,6 @@ jobs:
aztec_manifest_key: end-to-end
<<: *defaults_e2e_test


e2e-outbox:
docker:
- image: aztecprotocol/alpine-build-image
Expand Down Expand Up @@ -1221,7 +1220,7 @@ defaults: &defaults
- slack/notify:
event: fail
branch_pattern: "master"

bb_acir_tests: &bb_acir_tests
requires:
- barretenberg-x86_64-linux-clang-assert
Expand Down
8 changes: 8 additions & 0 deletions yarn-project/archiver/src/archiver/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export function getConfigEnvVars(): ArchiverConfig {
INBOX_CONTRACT_ADDRESS,
OUTBOX_CONTRACT_ADDRESS,
REGISTRY_CONTRACT_ADDRESS,
GAS_TOKEN_CONTRACT_ADDRESS,
GAS_PORTAL_CONTRACT_ADDRESS,
DATA_DIRECTORY,
} = process.env;
// Populate the relevant addresses for use by the archiver.
Expand All @@ -73,6 +75,12 @@ export function getConfigEnvVars(): ArchiverConfig {
registryAddress: REGISTRY_CONTRACT_ADDRESS ? EthAddress.fromString(REGISTRY_CONTRACT_ADDRESS) : EthAddress.ZERO,
inboxAddress: INBOX_CONTRACT_ADDRESS ? EthAddress.fromString(INBOX_CONTRACT_ADDRESS) : EthAddress.ZERO,
outboxAddress: OUTBOX_CONTRACT_ADDRESS ? EthAddress.fromString(OUTBOX_CONTRACT_ADDRESS) : EthAddress.ZERO,
gasTokenAddress: GAS_TOKEN_CONTRACT_ADDRESS
? EthAddress.fromString(GAS_TOKEN_CONTRACT_ADDRESS)
: EthAddress.ZERO,
gasPortalAddress: GAS_PORTAL_CONTRACT_ADDRESS
? EthAddress.fromString(GAS_PORTAL_CONTRACT_ADDRESS)
: EthAddress.ZERO,
};
return {
rpcUrl: ETHEREUM_HOST || 'http://127.0.0.1:8545/',
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/aztec.js/src/contract/contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ describe('Contract Class', () => {
registryAddress: EthAddress.random(),
inboxAddress: EthAddress.random(),
outboxAddress: EthAddress.random(),
gasTokenAddress: EthAddress.random(),
gasPortalAddress: EthAddress.random(),
};
const mockNodeInfo: NodeInfo = {
nodeVersion: 'vx.x.x',
Expand Down
24 changes: 16 additions & 8 deletions yarn-project/aztec.js/src/fee/native_fee_payment_method.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,41 @@
import { FunctionCall } from '@aztec/circuit-types';
import { FunctionData } from '@aztec/circuits.js';
import { AztecAddress, FunctionData } from '@aztec/circuits.js';
import { FunctionSelector } from '@aztec/foundation/abi';
import { Fr } from '@aztec/foundation/fields';
import { GasTokenAddress } from '@aztec/protocol-contracts/gas-token';
import { getCanonicalGasTokenAddress } from '@aztec/protocol-contracts/gas-token';

import { Wallet } from '../account/wallet.js';
import { FeePaymentMethod } from './fee_payment_method.js';

/**
* Pay fee directly in the native gas token.
*/
export class NativeFeePaymentMethod implements FeePaymentMethod {
static #GAS_TOKEN = GasTokenAddress;
#gasTokenAddress: AztecAddress;

constructor() {}
private constructor(canonicalGasTokenAddress: AztecAddress) {
this.#gasTokenAddress = canonicalGasTokenAddress;
}

static async create(wallet: Wallet): Promise<NativeFeePaymentMethod> {
const nodeInfo = await wallet.getNodeInfo();
return new NativeFeePaymentMethod(getCanonicalGasTokenAddress(nodeInfo.l1ContractAddresses.gasPortalAddress));
}

/**
* Gets the native gas asset used to pay the fee.
* @returns The asset used to pay the fee.
*/
getAsset() {
return NativeFeePaymentMethod.#GAS_TOKEN;
return this.#gasTokenAddress;
}

/**
* The contract responsible for fee payment. This will be the same as the asset.
* @returns The contract address responsible for holding the fee payment.
*/
getPaymentContract() {
return NativeFeePaymentMethod.#GAS_TOKEN;
return this.#gasTokenAddress;
}

/**
Expand All @@ -46,12 +54,12 @@ export class NativeFeePaymentMethod implements FeePaymentMethod {
getFunctionCalls(feeLimit: Fr): Promise<FunctionCall[]> {
return Promise.resolve([
{
to: NativeFeePaymentMethod.#GAS_TOKEN,
to: this.#gasTokenAddress,
functionData: new FunctionData(FunctionSelector.fromSignature('check_balance(Field)'), false),
args: [feeLimit],
},
{
to: NativeFeePaymentMethod.#GAS_TOKEN,
to: this.#gasTokenAddress,
functionData: new FunctionData(FunctionSelector.fromSignature('pay_fee(Field)'), false),
args: [feeLimit],
},
Expand Down
12 changes: 12 additions & 0 deletions yarn-project/aztec/src/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ import { retryUntil } from '@aztec/foundation/retry';
import {
AvailabilityOracleAbi,
AvailabilityOracleBytecode,
GasPortalAbi,
GasPortalBytecode,
InboxAbi,
InboxBytecode,
OutboxAbi,
OutboxBytecode,
PortalERC20Abi,
PortalERC20Bytecode,
RegistryAbi,
RegistryBytecode,
RollupAbi,
Expand Down Expand Up @@ -98,6 +102,14 @@ export async function deployContractsToL1(
contractAbi: RollupAbi,
contractBytecode: RollupBytecode,
},
gasToken: {
contractAbi: PortalERC20Abi,
contractBytecode: PortalERC20Bytecode,
},
gasPortal: {
contractAbi: GasPortalAbi,
contractBytecode: GasPortalBytecode,
},
};

aztecNodeConfig.l1Contracts = (
Expand Down
17 changes: 16 additions & 1 deletion yarn-project/cli/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import { type L1ContractArtifactsForDeployment } from '@aztec/aztec.js/ethereum'
import { type PXE } from '@aztec/aztec.js/interfaces/pxe';
import { DebugLogger, LogFn } from '@aztec/foundation/log';
import { NoirPackageConfig } from '@aztec/foundation/noir';
import { AvailabilityOracleAbi, AvailabilityOracleBytecode } from '@aztec/l1-artifacts';
import {
AvailabilityOracleAbi,
AvailabilityOracleBytecode,
GasPortalAbi,
GasPortalBytecode,
PortalERC20Abi,
PortalERC20Bytecode,
} from '@aztec/l1-artifacts';

import TOML from '@iarna/toml';
import { CommanderError, InvalidArgumentError } from 'commander';
Expand Down Expand Up @@ -85,6 +92,14 @@ export async function deployAztecContracts(
contractAbi: RollupAbi,
contractBytecode: RollupBytecode,
},
gasToken: {
contractAbi: PortalERC20Abi,
contractBytecode: PortalERC20Bytecode,
},
gasPortal: {
contractAbi: GasPortalAbi,
contractBytecode: GasPortalBytecode,
},
};
return await deployL1Contracts(chain.rpcUrl, account, chain.chainInfo, debugLogger, l1Artifacts);
}
Expand Down
7 changes: 4 additions & 3 deletions yarn-project/end-to-end/src/e2e_dapp_subscription.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
AccountWalletWithPrivateKey,
AztecAddress,
EthAddress,
FeePaymentMethod,
Fr,
PrivateFeePaymentMethod,
Expand All @@ -16,7 +17,7 @@ import {
FPCContract,
GasTokenContract,
} from '@aztec/noir-contracts.js';
import { GasTokenAddress } from '@aztec/protocol-contracts/gas-token';
import { getCanonicalGasTokenAddress } from '@aztec/protocol-contracts/gas-token';

import { jest } from '@jest/globals';

Expand Down Expand Up @@ -63,13 +64,13 @@ describe('e2e_dapp_subscription', () => {

beforeAll(async () => {
process.env.PXE_URL = '';
e2eContext = await setup(3, { deployProtocolContracts: true });
e2eContext = await setup(3, { deployGasToken: true });
await publicDeployAccounts(e2eContext.wallet, e2eContext.accounts);

const { wallets, accounts, aztecNode } = e2eContext;

// this should be a SignerlessWallet but that can't call public functions directly
gasTokenContract = await GasTokenContract.at(GasTokenAddress, wallets[0]);
gasTokenContract = await GasTokenContract.at(getCanonicalGasTokenAddress(EthAddress.ZERO), wallets[0]);

aliceAddress = accounts.at(0)!.address;
bobAddress = accounts.at(1)!.address;
Expand Down
5 changes: 3 additions & 2 deletions yarn-project/end-to-end/src/e2e_fees.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ describe('e2e_fees', () => {
let bananaPrivateBalances: BalancesFn;

beforeAll(async () => {
process.env.PXE_URL = '';
e2eContext = await setup(3);
e2eContext = await setup(3, {
deployGasToken: true,
});

const { accounts, logger, aztecNode, pxe, deployL1ContractsValues, wallets } = e2eContext;

Expand Down
35 changes: 25 additions & 10 deletions yarn-project/end-to-end/src/fixtures/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ import { deployInstance, registerContractClass } from '@aztec/aztec.js/deploymen
import {
AvailabilityOracleAbi,
AvailabilityOracleBytecode,
GasPortalAbi,
GasPortalBytecode,
InboxAbi,
InboxBytecode,
OutboxAbi,
OutboxBytecode,
PortalERC20Abi,
PortalERC20Bytecode,
RegistryAbi,
RegistryBytecode,
RollupAbi,
Expand Down Expand Up @@ -118,6 +122,14 @@ export const setupL1Contracts = async (
contractAbi: RollupAbi,
contractBytecode: RollupBytecode,
},
gasToken: {
contractAbi: PortalERC20Abi,
contractBytecode: PortalERC20Bytecode,
},
gasPortal: {
contractAbi: GasPortalAbi,
contractBytecode: GasPortalBytecode,
},
};
return await deployL1Contracts(l1RpcUrl, account, foundry, logger, l1Artifacts);
};
Expand Down Expand Up @@ -183,7 +195,7 @@ async function setupWithRemoteEnvironment(
config: AztecNodeConfig,
logger: DebugLogger,
numberOfAccounts: number,
deployProtocolContracts = false,
deployGasToken = false,
) {
// we are setting up against a remote environment, l1 contracts are already deployed
const aztecNodeUrl = getAztecUrl();
Expand Down Expand Up @@ -221,8 +233,10 @@ async function setupWithRemoteEnvironment(
const cheatCodes = CheatCodes.create(config.rpcUrl, pxeClient!);
const teardown = () => Promise.resolve();

if (deployProtocolContracts) {
await deployPublicProtocolContracts(wallets[0]);
if (deployGasToken) {
// this contract might already have been deployed
// the following function is idempotent
await deployCanonicalGasToken(wallets[0]);
}

return {
Expand All @@ -247,8 +261,8 @@ type SetupOptions = {
/** Previously deployed contracts on L1 */
deployL1ContractsValues?: DeployL1Contracts;

/** Deploy protocol contracts */
deployProtocolContracts?: boolean;
/** Deploy the gas token contract on L2 */
deployGasToken?: boolean;
} & Partial<AztecNodeConfig>;

/** Context for an end-to-end test as returned by the `setup` function */
Expand Down Expand Up @@ -308,7 +322,7 @@ export async function setup(

if (PXE_URL) {
// we are setting up against a remote environment, l1 contracts are assumed to already be deployed
return await setupWithRemoteEnvironment(hdAccount, config, logger, numberOfAccounts, opts.deployProtocolContracts);
return await setupWithRemoteEnvironment(hdAccount, config, logger, numberOfAccounts, opts.deployGasToken);
}

const deployL1ContractsValues =
Expand All @@ -330,10 +344,10 @@ export async function setup(

const { pxe, accounts, wallets } = await setupPXEService(numberOfAccounts, aztecNode!, pxeOpts, logger);

if (opts.deployProtocolContracts) {
if (opts.deployGasToken) {
// this should be a neutral wallet, but the SignerlessWallet only accepts a single function call
// and this needs two: one to register the class and another to deploy the instance
await deployPublicProtocolContracts(wallets[0]);
await deployCanonicalGasToken(wallets[0]);
}

const cheatCodes = CheatCodes.create(config.rpcUrl, pxe!);
Expand Down Expand Up @@ -493,9 +507,10 @@ export async function expectMapping<K, V>(
/**
* Deploy the protocol contracts to a running instance.
*/
export async function deployPublicProtocolContracts(deployer: Wallet) {
export async function deployCanonicalGasToken(deployer: Wallet) {
// "deploy" the Gas token as it contains public functions
const canonicalGasToken = getCanonicalGasToken();
const gasPortalAddress = (await deployer.getNodeInfo()).l1ContractAddresses.gasPortalAddress;
const canonicalGasToken = getCanonicalGasToken(gasPortalAddress);

if (await deployer.isContractClassPubliclyRegistered(canonicalGasToken.contractClass.id)) {
return;
Expand Down
Loading

0 comments on commit 2b2e931

Please sign in to comment.