Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Take a deep copy of circuit inputs for proving #5777

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 47 additions & 47 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -531,35 +531,35 @@ jobs:
# Semantics are similar to Dockerfile

# NOTE: Unlike other e2e, these will be re-enabled here as currently the logs functionality is not in the new earthfile setup
# bench-publish-rollup:
# steps:
# - *checkout
# - *setup_env
# - run:
# name: "Benchmark"
# command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_publish_rollup.test.ts DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees
# aztec_manifest_key: end-to-end
# <<: *defaults_e2e_test

# bench-process-history:
# steps:
# - *checkout
# - *setup_env
# - run:
# name: "Benchmark"
# command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_process_history.test.ts DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees
# aztec_manifest_key: end-to-end
# <<: *defaults_e2e_test

# bench-tx-size:
# steps:
# - *checkout
# - *setup_env
# - run:
# name: "Benchmark"
# command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_tx_size_fees.test.ts ENABLE_GAS=1 DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees
# aztec_manifest_key: end-to-end
# <<: *defaults_e2e_test
bench-publish-rollup:
steps:
- *checkout
- *setup_env
- run:
name: "Benchmark"
command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_publish_rollup.test.ts DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees
aztec_manifest_key: end-to-end
<<: *defaults_e2e_test

bench-process-history:
steps:
- *checkout
- *setup_env
- run:
name: "Benchmark"
command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_process_history.test.ts DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees
aztec_manifest_key: end-to-end
<<: *defaults_e2e_test

bench-tx-size:
steps:
- *checkout
- *setup_env
- run:
name: "Benchmark"
command: cond_spot_run_compose end-to-end 4 ./scripts/docker-compose-no-sandbox.yml TEST=benchmarks/bench_tx_size_fees.test.ts ENABLE_GAS=1 DEBUG=aztec:benchmarks:*,aztec:sequencer,aztec:sequencer:*,aztec:world_state,aztec:merkle_trees
aztec_manifest_key: end-to-end
<<: *defaults_e2e_test

build-docs:
machine:
Expand Down Expand Up @@ -597,15 +597,15 @@ jobs:
name: "Noop"
command: echo Noop

# bench-summary:
# machine:
# image: default
# steps:
# - *checkout
# - *setup_env
# - run:
# name: "Assemble benchmark summary from uploaded logs"
# command: ./scripts/ci/assemble_e2e_benchmark.sh
bench-summary:
machine:
image: default
steps:
- *checkout
- *setup_env
- run:
name: "Assemble benchmark summary from uploaded logs"
command: ./scripts/ci/assemble_e2e_benchmark.sh

# Deploy & release jobs.
deploy-and-release:
Expand Down Expand Up @@ -898,15 +898,15 @@ workflows:
<<: *defaults

# Benchmark jobs.
# - bench-publish-rollup: *e2e_test
# - bench-process-history: *e2e_test
# - bench-tx-size: *e2e_test
# - bench-summary:
# requires:
# - bench-publish-rollup
# - bench-process-history
# - bench-tx-size
# <<: *defaults
- bench-publish-rollup: *e2e_test
- bench-process-history: *e2e_test
- bench-tx-size: *e2e_test
- bench-summary:
requires:
- bench-publish-rollup
- bench-process-history
- bench-tx-size
<<: *defaults

# Production releases.
- deploy-and-release: *defaults_deploy
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { makePublicCallData } from '../../tests/factories.js';
import { PublicCallData } from './public_call_data.js';

describe('PublicCallData', () => {
it('PublicCallData after serialization and deserialization is equal to the original', () => {
const original = makePublicCallData(123, true);
const serialized = PublicCallData.fromBuffer(original.toBuffer());
expect(original).toEqual(serialized);
});
});
26 changes: 20 additions & 6 deletions yarn-project/circuits.js/src/structs/kernel/public_call_data.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { type Fr } from '@aztec/foundation/fields';
import { type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';

import { type MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL } from '../../constants.gen.js';
import { type CallRequest } from '../call_request.js';
import { type Proof } from '../proof.js';
import { type PublicCallStackItem } from '../public_call_stack_item.js';
import { MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL } from '../../constants.gen.js';
import { CallRequest } from '../call_request.js';
import { Proof } from '../proof.js';
import { PublicCallStackItem } from '../public_call_stack_item.js';

/**
* Public calldata assembled from the kernel execution result and proof.
Expand Down Expand Up @@ -42,4 +42,18 @@ export class PublicCallData {
this.bytecodeHash,
);
}

static fromBuffer(buffer: BufferReader | Buffer) {
const reader = BufferReader.asReader(buffer);
return new PublicCallData(
reader.readObject(PublicCallStackItem),
reader.readArray<CallRequest, typeof MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL>(
MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,
CallRequest,
),
reader.readObject(Proof),
reader.readObject(Fr),
reader.readObject(Fr),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { makePublicKernelCircuitPrivateInputs } from '../../tests/factories.js';
import { PublicKernelCircuitPrivateInputs } from './public_kernel_circuit_private_inputs.js';

describe('PublicKernelCircuitPrivateInputs', () => {
it('PublicKernelCircuitPrivateInputs after serialization and deserialization is equal to the original', () => {
const original = makePublicKernelCircuitPrivateInputs(123);
const serialized = PublicKernelCircuitPrivateInputs.fromBuffer(original.toBuffer());
expect(original).toEqual(serialized);
});

it('PublicKernelCircuitPrivateInputs after clone is equal to the original', () => {
const original = makePublicKernelCircuitPrivateInputs(123);
const serialized = original.clone();
expect(original).toEqual(serialized);
expect(original).not.toBe(serialized);
});
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { serializeToBuffer } from '@aztec/foundation/serialize';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';

import { type PublicCallData } from './public_call_data.js';
import { type PublicKernelData } from './public_kernel_data.js';
import { PublicCallData } from './public_call_data.js';
import { PublicKernelData } from './public_kernel_data.js';

/**
* Inputs to the public kernel circuit.
Expand All @@ -21,4 +21,15 @@ export class PublicKernelCircuitPrivateInputs {
toBuffer() {
return serializeToBuffer(this.previousKernel, this.publicCall);
}

static fromBuffer(buffer: BufferReader | Buffer) {
const reader = BufferReader.asReader(buffer);
const previousKernel = reader.readObject(PublicKernelData);
const publicCall = reader.readObject(PublicCallData);
return new PublicKernelCircuitPrivateInputs(previousKernel, publicCall);
}

clone() {
return PublicKernelCircuitPrivateInputs.fromBuffer(this.toBuffer());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { makePublicKernelTailCircuitPrivateInputs } from '../../tests/factories.js';
import { PublicKernelTailCircuitPrivateInputs } from './public_kernel_tail_circuit_private_inputs.js';

describe('PublicKernelTailCircuitPrivateInputs', () => {
it('PublicKernelTailCircuitPrivateInputs after serialization and deserialization is equal to the original', () => {
const original = makePublicKernelTailCircuitPrivateInputs(123);
const serialized = PublicKernelTailCircuitPrivateInputs.fromBuffer(original.toBuffer());
expect(original).toEqual(serialized);
});

it('PublicKernelTailCircuitPrivateInputs after clone is equal to the original', () => {
const original = makePublicKernelTailCircuitPrivateInputs(123);
const serialized = original.clone();
expect(original).toEqual(serialized);
expect(original).not.toBe(serialized);
});
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { serializeToBuffer } from '@aztec/foundation/serialize';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';

import { type NullifierNonExistentReadRequestHints } from '../non_existent_read_request_hints.js';
import { type NullifierReadRequestHints } from '../read_request_hints.js';
import { type PublicKernelData } from './public_kernel_data.js';
import {
type NullifierNonExistentReadRequestHints,
nullifierNonExistentReadRequestHintsFromBuffer,
} from '../non_existent_read_request_hints.js';
import { type NullifierReadRequestHints, nullifierReadRequestHintsFromBuffer } from '../read_request_hints.js';
import { PublicKernelData } from './public_kernel_data.js';

/**
* Inputs to the public kernel circuit.
Expand Down Expand Up @@ -30,4 +33,17 @@ export class PublicKernelTailCircuitPrivateInputs {
this.nullifierNonExistentReadRequestHints,
);
}

static fromBuffer(buffer: Buffer | BufferReader) {
const reader = BufferReader.asReader(buffer);
return new PublicKernelTailCircuitPrivateInputs(
reader.readObject(PublicKernelData),
nullifierReadRequestHintsFromBuffer(reader),
nullifierNonExistentReadRequestHintsFromBuffer(reader),
);
}

clone() {
return PublicKernelTailCircuitPrivateInputs.fromBuffer(this.toBuffer());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ export class NonExistentReadRequestHints<
}

toBuffer() {
return serializeToBuffer(this.nonMembershipHints, this.nextPendingValueIndices);
return serializeToBuffer(
this.nonMembershipHints,
this.nextPendingValueIndices,
this.sortedPendingValues,
this.sortedPendingValueHints,
);
}
}

Expand Down
7 changes: 4 additions & 3 deletions yarn-project/simulator/src/public/abstract_phase_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,15 @@ export abstract class AbstractPhaseManager {
): Promise<[PublicKernelCircuitPrivateInputs, PublicKernelCircuitPublicInputs]> {
const previousKernel = this.getPreviousKernelData(previousOutput, previousProof);

// We take a deep copy (clone) of these inputs to be passed to the prover
const inputs = new PublicKernelCircuitPrivateInputs(previousKernel, callData);
switch (this.phase) {
case PublicKernelPhase.SETUP:
return [inputs, await this.publicKernel.publicKernelCircuitSetup(inputs)];
return [inputs.clone(), await this.publicKernel.publicKernelCircuitSetup(inputs)];
case PublicKernelPhase.APP_LOGIC:
return [inputs, await this.publicKernel.publicKernelCircuitAppLogic(inputs)];
return [inputs.clone(), await this.publicKernel.publicKernelCircuitAppLogic(inputs)];
case PublicKernelPhase.TEARDOWN:
return [inputs, await this.publicKernel.publicKernelCircuitTeardown(inputs)];
return [inputs.clone(), await this.publicKernel.publicKernelCircuitTeardown(inputs)];
default:
throw new Error(`No public kernel circuit for inputs`);
}
Expand Down
4 changes: 3 additions & 1 deletion yarn-project/simulator/src/public/tail_phase_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,14 @@ export class TailPhaseManager extends AbstractPhaseManager {
endNonRevertibleData.newNullifiers,
end.newNullifiers,
);

// We take a deep copy (clone) of these to pass to the prover
const inputs = new PublicKernelTailCircuitPrivateInputs(
previousKernel,
nullifierReadRequestHints,
nullifierNonExistentReadRequestHints,
);
return [inputs, await this.publicKernel.publicKernelCircuitTail(inputs)];
return [inputs.clone(), await this.publicKernel.publicKernelCircuitTail(inputs)];
}

private sortNoteHashes<N extends number>(noteHashes: Tuple<SideEffect, N>): Tuple<Fr, N> {
Expand Down
Loading