Skip to content

Commit

Permalink
representing body hash as buffer in TS
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Jan 13, 2024
1 parent fc66868 commit 19381d9
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 27 deletions.
12 changes: 12 additions & 0 deletions yarn-project/circuits.js/src/structs/header.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { makeHeader } from '../tests/factories.js';
import { Header } from './header.js';

describe('Header', () => {
it(`serializes to buffer and deserializes it back`, () => {
const randomInt = Math.floor(Math.random() * 1000);
const expected = makeHeader(randomInt, undefined);
const buffer = expected.toBuffer();
const res = Header.fromBuffer(buffer);
expect(res).toEqual(expected);
});
});
14 changes: 9 additions & 5 deletions yarn-project/circuits.js/src/structs/header.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';

import { NUM_FIELDS_PER_SHA256 } from '../constants.gen.js';
import { GlobalVariables } from './global_variables.js';
import { AppendOnlyTreeSnapshot } from './rollup/append_only_tree_snapshot.js';
import { StateReference } from './state_reference.js';

export const NUM_BYTES_PER_SHA256 = 32;

/** A header of an L2 block. */
export class Header {
constructor(
/** Snapshot of archive before the block is applied. */
public lastArchive: AppendOnlyTreeSnapshot,
/** Hash of the body of an L2 block. */
public bodyHash: [Fr, Fr],
public bodyHash: Buffer,
/** State reference. */
public state: StateReference,
/** Global variables of an L2 block. */
public globalVariables: GlobalVariables,
) {}
) {
if (bodyHash.length !== 32) {
throw new Error('Body hash buffer must be 32 bytes');
}
}

toBuffer() {
// Note: The order here must match the order in the HeaderDecoder solidity library.
Expand All @@ -28,7 +32,7 @@ export class Header {
const reader = BufferReader.asReader(buffer);
return new Header(
reader.readObject(AppendOnlyTreeSnapshot),
reader.readArray(NUM_FIELDS_PER_SHA256, Fr) as [Fr, Fr],
reader.readBytes(NUM_BYTES_PER_SHA256),
reader.readObject(StateReference),
reader.readObject(GlobalVariables),
);
Expand Down
17 changes: 0 additions & 17 deletions yarn-project/circuits.js/src/structs/rollup/root_rollup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,23 +95,6 @@ export class RootRollupPublicInputs {
return new RootRollupPublicInputs(...RootRollupPublicInputs.getFields(fields));
}

/**
* Returns the sha256 hash of the calldata.
* @returns The sha256 hash of the calldata.
*/
public sha256CalldataHash(): Buffer {
const high = this.header.bodyHash[0].toBuffer();
const low = this.header.bodyHash[1].toBuffer();

const hash = Buffer.alloc(32);
for (let i = 0; i < 16; i++) {
hash[i] = high[i + 16];
hash[i + 16] = low[i + 16];
}

return hash;
}

/**
* Deserializes a buffer into a `RootRollupPublicInputs` object.
* @param buffer - The buffer to deserialize.
Expand Down
6 changes: 4 additions & 2 deletions yarn-project/circuits.js/src/tests/factories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { AztecAddress } from '@aztec/foundation/aztec-address';
import { EthAddress } from '@aztec/foundation/eth-address';
import { numToUInt32BE } from '@aztec/foundation/serialize';

import { randomBytes } from 'crypto';

import { SchnorrSignature } from '../barretenberg/index.js';
import {
ARCHIVE_HEIGHT,
Expand Down Expand Up @@ -101,7 +103,7 @@ import {
WitnessedPublicCallData,
} from '../index.js';
import { GlobalVariables } from '../structs/global_variables.js';
import { Header } from '../structs/header.js';
import { Header, NUM_BYTES_PER_SHA256 } from '../structs/header.js';

/**
* Creates an arbitrary side effect object with the given seed.
Expand Down Expand Up @@ -882,7 +884,7 @@ export function makeRootRollupPublicInputs(
export function makeHeader(seed = 0, globalVariables: GlobalVariables | undefined): Header {
return new Header(
makeAppendOnlyTreeSnapshot(seed + 0x100),
[new Fr(5n), new Fr(6n)],
randomBytes(NUM_BYTES_PER_SHA256),
makeStateReference(seed + 0x200),
globalVariables ?? makeGlobalVariables((seed += 0x100)),
);
Expand Down
15 changes: 13 additions & 2 deletions yarn-project/noir-protocol-circuits/src/type_conversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ import {
TxContext,
TxRequest,
} from '@aztec/circuits.js';
import { Tuple, mapTuple } from '@aztec/foundation/serialize';
import { Tuple, from2Fields, mapTuple } from '@aztec/foundation/serialize';

import {
BlockHeader as BlockHeaderNoir,
Expand Down Expand Up @@ -137,6 +137,8 @@ import {
AppendOnlyTreeSnapshot as AppendOnlyTreeSnapshotNoir,
BaseOrMergeRollupPublicInputs as BaseOrMergeRollupPublicInputsNoir,
ConstantRollupData as ConstantRollupDataNoir,
Field,
FixedLengthArray,
GlobalVariables as GlobalVariablesNoir,
Header as HeaderNoir,
PartialStateReference as PartialStateReferenceNoir,
Expand Down Expand Up @@ -678,6 +680,15 @@ export function mapTupleFromNoir<T, N extends number, M>(
return Array.from({ length }, (_, idx) => mapper(noirArray[idx])) as Tuple<M, N>;
}

/**
* Maps a SHA256 hash from noir to the parsed type.
* @param hash - The hash as it is represented in Noir (2 fields).
* @returns The hash represented as a 32 bytes long buffer.
*/
export function mapSha256HashFromNoir(hash: FixedLengthArray<Field, 2>): Buffer {
return from2Fields(mapFieldFromNoir(hash[0]), mapFieldFromNoir(hash[1]));
}

/**
* Maps optionally revealed data from noir to the parsed type.
* @param optionallyRevealedData - The noir optionally revealed data.
Expand Down Expand Up @@ -1318,7 +1329,7 @@ export function mapRootRollupPublicInputsFromNoir(
export function mapHeaderFromNoir(header: HeaderNoir): Header {
return new Header(
mapAppendOnlyTreeSnapshotFromNoir(header.last_archive),
mapTupleFromNoir(header.body_hash, 2, mapFieldFromNoir),
mapSha256HashFromNoir(header.body_hash),
mapStateReferenceFromNoir(header.state),
mapGlobalVariablesFromNoir(header.global_variables),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export class SoloBlockBuilder implements BlockBuilder {
newUnencryptedLogs,
});

if (!l2Block.getCalldataHash().equals(circuitsOutput.sha256CalldataHash())) {
if (!l2Block.getCalldataHash().equals(circuitsOutput.header.bodyHash)) {
throw new Error(
`Calldata hash mismatch, ${l2Block.getCalldataHash().toString('hex')} == ${circuitsOutput
.sha256CalldataHash()
Expand Down

0 comments on commit 19381d9

Please sign in to comment.