Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Mar 22, 2024
1 parent 4f14dfb commit 3ad601e
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 29 deletions.
2 changes: 1 addition & 1 deletion docs/docs/developers/debugging/sandbox-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ Users may create a proof against a historical state in Aztec. The rollup circuit

## Archiver Errors

- "No L1 to L2 message found for message hash ${messageHash.toString()}" - happens when the L1 to L2 message doesn't exist or is "pending", when the user has sent a message on L1 via the Inbox contract but it has yet to be included in an L2 block by the sequencer - user has to wait for enough blocks to progress and for the archiver to sync the respective L2 block. You can get the sequencer to pick it up by doing 2 arbitrary transaction on L2 (eg. send DAI to yourself 2 times). This would give the sequencer a transaction to process and as a side effect it would consume 2 subtrees of new messages from the Inbox contract. 2 subtrees needs to be consumed and not just 1 because there is a 1 block lag to prevent the subtree from changing when the sequencer is proving.
- "No non-nullified L1 to L2 message found for message hash ${messageHash.toString()}" - happens when the L1 to L2 message doesn't exist or is "pending", when the user has sent a message on L1 via the Inbox contract but it has yet to be included in an L2 block by the sequencer - user has to wait for enough blocks to progress and for the archiver to sync the respective L2 block. You can get the sequencer to pick it up by doing 2 arbitrary transaction on L2 (eg. send DAI to yourself 2 times). This would give the sequencer a transaction to process and as a side effect it would consume 2 subtrees of new messages from the Inbox contract. 2 subtrees needs to be consumed and not just 1 because there is a 1 block lag to prevent the subtree from changing when the sequencer is proving.

- "Block number mismatch: expected ${l2BlockNum} but got ${block.number}" - The archiver keeps track of the next expected L2 block number. It throws this error if it got a different one when trying to sync with the rollup contract's events on L1.

Expand Down
4 changes: 4 additions & 0 deletions yarn-project/circuits.js/src/hash/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,7 @@ export function computeNullifierHash(input: SideEffectLinkedToNoteHash) {
export function computeMessageSecretHash(secretMessage: Fr) {
return pedersenHash([secretMessage.toBuffer()], GeneratorIndex.L1_TO_L2_MESSAGE_SECRET);
}

export function computeL1ToL2MessageNullifier(messageHash: Fr, secret: Fr, messageIndex: bigint) {
return pedersenHash([messageHash, secret, messageIndex], GeneratorIndex.NULLIFIER);
}
4 changes: 2 additions & 2 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 @@ -178,7 +178,7 @@ describe('e2e_cross_chain_messaging', () => {
.withWallet(user2Wallet)
.methods.claim_private(secretHashForL2MessageConsumption, bridgeAmount, secretForL2MessageConsumption)
.simulate(),
).rejects.toThrow(`No L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`);
).rejects.toThrow(`No non-nullified L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`);

// send the right one -
const consumptionReceipt = await l2Bridge
Expand Down Expand Up @@ -258,6 +258,6 @@ describe('e2e_cross_chain_messaging', () => {
.withWallet(user2Wallet)
.methods.claim_public(ownerAddress, bridgeAmount, secretForL2MessageConsumption)
.simulate(),
).rejects.toThrow(`Message ${wrongMessage.hash().toString()} not found`);
).rejects.toThrow(`No non-nullified L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`);
}, 120_000);
});
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ describe('e2e_public_cross_chain_messaging', () => {
// user2 tries to consume this message and minting to itself -> should fail since the message is intended to be consumed only by owner.
await expect(
l2Bridge.withWallet(user2Wallet).methods.claim_public(user2Wallet.getAddress(), bridgeAmount, secret).simulate(),
).rejects.toThrow(`Message ${wrongMessage.hash().toString()} not found`);
).rejects.toThrow(`No non-nullified L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`);

// user2 consumes owner's L1-> L2 message on bridge contract and mints public tokens on L2
logger("user2 consumes owner's message on L2 Publicly");
Expand Down Expand Up @@ -223,7 +223,7 @@ describe('e2e_public_cross_chain_messaging', () => {

await expect(
l2Bridge.withWallet(user2Wallet).methods.claim_private(secretHash, bridgeAmount, secret).simulate(),
).rejects.toThrow(`No L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`);
).rejects.toThrow(`No non-nullified L1 to L2 message found for message hash ${wrongMessage.hash().toString()}`);
}, 60_000);

// Note: We register one portal address when deploying contract but that address is no-longer the only address
Expand Down
10 changes: 6 additions & 4 deletions yarn-project/foundation/src/crypto/pedersen/pedersen.wasm.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { BarretenbergSync, Fr as FrBarretenberg } from '@aztec/bb.js';

import { Fr } from '../../fields/fields.js';
import { Bufferable, serializeToBufferArray } from '../../serialize/serialize.js';

/**
* Create a pedersen commitment (point) from an array of input fields.
Expand All @@ -21,16 +22,17 @@ export function pedersenCommit(input: Buffer[]) {
* Create a pedersen hash (field) from an array of input fields.
* Left pads any inputs less than 32 bytes.
*/
export function pedersenHash(input: Buffer[], index = 0): Fr {
if (!input.every(i => i.length <= 32)) {
export function pedersenHash(input: Bufferable[], index = 0): Fr {
let bufferredInput = serializeToBufferArray(input);
if (!bufferredInput.every(i => i.length <= 32)) {
throw new Error('All Pedersen Hash input buffers must be <= 32 bytes.');
}
input = input.map(i => (i.length < 32 ? Buffer.concat([Buffer.alloc(32 - i.length, 0), i]) : i));
bufferredInput = bufferredInput.map(i => (i.length < 32 ? Buffer.concat([Buffer.alloc(32 - i.length, 0), i]) : i));
return Fr.fromBuffer(
Buffer.from(
BarretenbergSync.getSingleton()
.pedersenHash(
input.map(i => new FrBarretenberg(i)),
bufferredInput.map(i => new FrBarretenberg(i)),
index,
)
.toBuffer(),
Expand Down
13 changes: 4 additions & 9 deletions yarn-project/pxe/src/simulator_oracle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@ import {
EthAddress,
Fr,
FunctionSelector,
GeneratorIndex,
Header,
L1_TO_L2_MSG_TREE_HEIGHT,
L1_TO_L2_MSG_TREE_HEIGHT
} from '@aztec/circuits.js';
import { FunctionArtifactWithDebugMetadata, getFunctionArtifactWithDebugMetadata } from '@aztec/foundation/abi';
import { pedersenHash } from '@aztec/foundation/crypto';
import { createDebugLogger } from '@aztec/foundation/log';
import { DBOracle, KeyPair, MessageLoadOracleInputs } from '@aztec/simulator';
import { ContractInstance } from '@aztec/types/contracts';

import { computeL1ToL2MessageNullifier } from '@aztec/circuits.js/hash';
import { ContractDataOracle } from '../contract_data_oracle/index.js';
import { PxeDatabase } from '../database/index.js';

Expand Down Expand Up @@ -137,7 +136,7 @@ export class SimulatorOracle implements DBOracle {
let messageIndex = 0n;
let siblingPath: SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>;

// We iterate over messages until we find one whose nullifier is not in the nullifier tree --> ewe need to check
// We iterate over messages until we find one whose nullifier is not in the nullifier tree --> we need to check
// for nullifiers because messages can have duplicates.
do {
const response = await this.aztecNode.getL1ToL2MessageMembershipWitness('latest', messageHash, messageIndex);
Expand All @@ -146,11 +145,7 @@ export class SimulatorOracle implements DBOracle {
}
[messageIndex, siblingPath] = response;

// TODO: create separate helper function
const messageNullifier = pedersenHash(
[messageHash, secret, new Fr(messageIndex)].map(v => v.toBuffer()),
GeneratorIndex.NULLIFIER,
);
const messageNullifier = computeL1ToL2MessageNullifier(messageHash, secret, messageIndex);
nullifierIndex = await this.getNullifierIndex(messageNullifier);
} while (nullifierIndex !== undefined);

Expand Down
14 changes: 3 additions & 11 deletions yarn-project/sequencer-client/src/simulator/public_executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
L1ToL2MessageSource,
MerkleTreeId,
NullifierMembershipWitness,
SiblingPath,
Tx,
UnencryptedL2Log,
} from '@aztec/circuit-types';
Expand All @@ -13,14 +12,12 @@ import {
EthAddress,
Fr,
FunctionSelector,
GeneratorIndex,
L1_TO_L2_MSG_TREE_HEIGHT,
NULLIFIER_TREE_HEIGHT,
NullifierLeafPreimage,
PublicDataTreeLeafPreimage,
} from '@aztec/circuits.js';
import { computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash';
import { pedersenHash } from '@aztec/foundation/crypto';
import { computeL1ToL2MessageNullifier, computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash';
import { createDebugLogger } from '@aztec/foundation/log';
import { getCanonicalClassRegistererAddress } from '@aztec/protocol-contracts/class-registerer';
import { CommitmentsDB, MessageLoadOracleInputs, PublicContractsDB, PublicStateDB } from '@aztec/simulator';
Expand Down Expand Up @@ -233,20 +230,15 @@ export class WorldStateDB implements CommitmentsDB {
let nullifierIndex: bigint | undefined;
let messageIndex: bigint | undefined;

// We iterate over messages until we find one whose nullifier is not in the nullifier tree --> ewe need to check
// We iterate over messages until we find one whose nullifier is not in the nullifier tree --> we need to check
// for nullifiers because messages can have duplicates.
do {
messageIndex = (await this.db.findLeafIndex(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, messageHash.toBuffer()))!;
if (messageIndex === undefined) {
throw new Error(`No non-nullified L1 to L2 message found for message hash ${messageHash.toString()}`);
}

// TODO: create separate helper function
const messageNullifier = pedersenHash(
[messageHash, secret, new Fr(messageIndex)].map(v => v.toBuffer()),
GeneratorIndex.NULLIFIER,
);

const messageNullifier = computeL1ToL2MessageNullifier(messageHash, secret, messageIndex);
nullifierIndex = await this.getNullifierIndex(messageNullifier);
} while (nullifierIndex !== undefined);

Expand Down

0 comments on commit 3ad601e

Please sign in to comment.