Skip to content

Commit

Permalink
fix: Take a deep copy of circuit inputs for proving (#5777)
Browse files Browse the repository at this point in the history
This PR ensures we take a copy of the circuit inputs during simulation
for use in proving.
  • Loading branch information
PhilWindle committed Apr 16, 2024
1 parent 8ebbe57 commit 785591e
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 65 deletions.
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 @@ -339,14 +339,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

0 comments on commit 785591e

Please sign in to comment.