Skip to content

Commit

Permalink
add test to get error codes out.
Browse files Browse the repository at this point in the history
  • Loading branch information
just-mitch committed Feb 2, 2025
1 parent 5f787bc commit 7298fdc
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ SCRIPT_NAME=$(basename "$0" .sh)
exec > >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log") 2> >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log" >&2)

export BOOTNODE_URL=${BOOTNODE_URL:-http://127.0.0.1:8080}
export NODE_URL=${NODE_URL:-${BOOTNODE_URL:-http://127.0.0.1:8080}}
export PXE_URL=${PXE_URL:-http://127.0.0.1:8079}
export ETHEREUM_HOST=${ETHEREUM_HOST:-http://127.0.0.1:8545}
export K8S=${K8S:-false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -583,26 +583,44 @@ describe('L1Publisher integration', () => {
await expect(publisher.enqueueProposeL2Block(block)).resolves.toEqual(true);

await expect(publisher.sendRequests()).resolves.toMatchObject({
errorMsg: expect.stringContaining('Rollup__InvalidBlobHash'),
errorMsg: expect.stringContaining('Rollup__InvalidInHash'),
});

// Test for both calls
// NOTE: First error is from the simulate fn, which isn't supported by anvil
expect(loggerErrorSpy).toHaveBeenCalledTimes(2);

expect(loggerErrorSpy).toHaveBeenNthCalledWith(1, 'Bundled [propose] transaction [failed]');
expect(loggerErrorSpy).toHaveBeenCalledTimes(3);

expect(loggerErrorSpy).toHaveBeenNthCalledWith(
1,
'Forwarder transaction failed',
undefined,
expect.objectContaining({
receipt: expect.objectContaining({
type: 'eip4844',
blockHash: expect.any(String),
blockNumber: expect.any(BigInt),
transactionHash: expect.any(String),
}),
}),
);
expect(loggerErrorSpy).toHaveBeenNthCalledWith(
2,
expect.stringContaining('Bundled [propose] transaction [failed]'),
);

expect(loggerErrorSpy).toHaveBeenNthCalledWith(
3,
expect.stringMatching(
/^Rollup process tx reverted\. The contract function "forward" reverted\. Error: Rollup__InvalidBlobHash/i,
/^Rollup process tx reverted\. The contract function "forward" reverted\. Error: Rollup__InvalidInHash/i,
),
undefined,
expect.objectContaining({
blockHash: expect.any(String),
blockHash: expect.any(Fr),
blockNumber: expect.any(Number),
slotNumber: expect.any(BigInt),
txHash: expect.any(String),
txCount: expect.any(Number),
blockTimestamp: expect.any(Number),
}),
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,6 @@ describe('e2e_gov_proposal', () => {
);
expect(votes).toEqual(roundDuration);
},
5 * 60000,
1000 * 60 * 5,
);
});
146 changes: 146 additions & 0 deletions yarn-project/ethereum/src/contracts/forwarder.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { EthAddress } from '@aztec/foundation/eth-address';
import { Fr } from '@aztec/foundation/fields';
import { type Logger, createLogger } from '@aztec/foundation/log';
import { GovernanceProposerAbi } from '@aztec/l1-artifacts/GovernanceProposerAbi';
import { TestERC20Abi } from '@aztec/l1-artifacts/TestERC20Abi';
import { TestERC20Bytecode } from '@aztec/l1-artifacts/TestERC20Bytecode';

import { type Anvil } from '@viem/anvil';
import {
type Chain,
type GetContractReturnType,
type HttpTransport,
type PublicClient,
encodeFunctionData,
getContract,
} from 'viem';
import { type PrivateKeyAccount, privateKeyToAccount } from 'viem/accounts';
import { foundry } from 'viem/chains';

import { DefaultL1ContractsConfig } from '../config.js';
import { type L1Clients, createL1Clients, deployL1Contract, deployL1Contracts } from '../deploy_l1_contracts.js';
import { L1TxUtils } from '../l1_tx_utils.js';
import { startAnvil } from '../test/start_anvil.js';
import { FormattedViemError } from '../utils.js';
import { ForwarderContract } from './forwarder.js';

describe('Forwarder', () => {
let anvil: Anvil;
let rpcUrl: string;
let privateKey: PrivateKeyAccount;
let logger: Logger;

let vkTreeRoot: Fr;
let protocolContractTreeRoot: Fr;
// let initialValidators: EthAddress[];
let l2FeeJuiceAddress: AztecAddress;
let walletClient: L1Clients['walletClient'];
let publicClient: L1Clients['publicClient'];
let forwarder: ForwarderContract;
let l1TxUtils: L1TxUtils;
// let rollupAddress: EthAddress;
let govProposerAddress: EthAddress;
let tokenAddress: EthAddress;
let tokenContract: GetContractReturnType<typeof TestERC20Abi, PublicClient<HttpTransport, Chain>>;
beforeAll(async () => {
logger = createLogger('ethereum:test:forwarder');
// this is the 6th address that gets funded by the junk mnemonic
privateKey = privateKeyToAccount('0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba');
vkTreeRoot = Fr.random();
protocolContractTreeRoot = Fr.random();
// initialValidators = times(3, EthAddress.random);
l2FeeJuiceAddress = await AztecAddress.random();

({ anvil, rpcUrl } = await startAnvil());

({ walletClient, publicClient } = createL1Clients(rpcUrl, privateKey));

const deployed = await deployL1Contracts(rpcUrl, privateKey, foundry, logger, {
...DefaultL1ContractsConfig,
salt: undefined,
vkTreeRoot,
protocolContractTreeRoot,
l2FeeJuiceAddress,
});

govProposerAddress = deployed.l1ContractAddresses.governanceProposerAddress;
// rollupAddress = deployed.l1ContractAddresses.rollupAddress;

forwarder = await ForwarderContract.create(
privateKey.address,
walletClient,
publicClient,
logger,
deployed.l1ContractAddresses.rollupAddress.toString(),
);

l1TxUtils = new L1TxUtils(publicClient, walletClient, logger);

const { address: erc20Address, txHash: erc20TxHash } = await deployL1Contract(
walletClient,
publicClient,
TestERC20Abi,
TestERC20Bytecode,
['test', 'TST', privateKey.address],
'0x42',
undefined,
logger,
);
expect(erc20TxHash).toBeDefined();
await publicClient.waitForTransactionReceipt({ hash: erc20TxHash! });
tokenAddress = erc20Address;
tokenContract = getContract({
address: tokenAddress.toString(),
abi: TestERC20Abi,
client: publicClient,
});

const freeForAllHash = await tokenContract.write.setFreeForAll([true], { account: privateKey });
await publicClient.waitForTransactionReceipt({ hash: freeForAllHash });

logger.info(`Token address: ${tokenAddress}`);
});

afterAll(async () => {
await anvil.stop();
});

it('gets good error messages', async () => {
expect(forwarder).toBeDefined();
const initialBalance = await tokenContract.read.balanceOf([privateKey.address]);
expect(initialBalance).toBe(0n);
const err = await forwarder
.forward(
[
// This one passes
{
to: tokenAddress.toString(),
data: encodeFunctionData({
abi: TestERC20Abi,
functionName: 'mint',
args: [privateKey.address, 100n],
}),
},

// This one fails
{
to: govProposerAddress.toString(),
data: encodeFunctionData({
abi: GovernanceProposerAbi,
functionName: 'vote',
args: [EthAddress.random().toString()],
}),
},
],
l1TxUtils,
undefined,
undefined,
logger,
)
.catch(err => err);
expect(err).toBeDefined();
expect(err).toBeInstanceOf(FormattedViemError);
expect(err.message).toMatch(/GovernanceProposer__OnlyProposerCanVote/);
});
});
2 changes: 1 addition & 1 deletion yarn-project/ethereum/src/contracts/forwarder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export class ForwarderContract {
const stats = await l1TxUtils.getTransactionStats(receipt.transactionHash);
return { receipt, gasPrice, stats };
} else {
logger.error('Forwarder transaction failed', { receipt });
logger.error('Forwarder transaction failed', undefined, { receipt });

const args = {
...forwarderFunctionData,
Expand Down
2 changes: 0 additions & 2 deletions yarn-project/ethereum/src/l1_tx_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -672,8 +672,6 @@ export class L1TxUtils {
}[] = [],
) {
try {
// NB: If this fn starts unexpectedly giving incorrect blob hash errors, it may be because the checkBlob
// bool is no longer at the slot below. To find the slot, run: forge inspect src/core/Rollup.sol:Rollup storage
await this.publicClient.simulateContract({
...args,
account: this.walletClient.account,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,7 @@ export class SequencerPublisher {
const kzg = Blob.getViemKzgInstance();
const { rollupData, simulationResult, blobEvaluationGas } = await this.prepareProposeTx(encodedData, timestamp);
const startBlock = await this.l1TxUtils.getBlockNumber();
const blockHash = await block.hash();

return this.addRequest({
action: 'propose',
Expand Down Expand Up @@ -687,7 +688,7 @@ export class SequencerPublisher {
this.log.error(`Rollup process tx reverted. ${errorMsg ?? 'No error message'}`, undefined, {
...block.getStats(),
txHash: receipt.transactionHash,
blockHash: block.hash().toString(),
blockHash,
slotNumber: block.header.globalVariables.slotNumber.toBigInt(),
});
}
Expand Down

0 comments on commit 7298fdc

Please sign in to comment.