Skip to content

Commit

Permalink
feat(avm): include initial tree roots in DB (#11360)
Browse files Browse the repository at this point in the history
We'll need the roots for the context and other stuff. I expect that `get_tree_roots()` will not lay constraints. I expect that the roots will be advanced via hints in, e.g, `emit_nullifier` (root before, root after).
  • Loading branch information
fcarreiro authored Jan 21, 2025
1 parent 55dd03c commit 4d149be
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 5 deletions.
14 changes: 13 additions & 1 deletion barretenberg/cpp/src/barretenberg/vm2/common/avm_inputs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,25 @@ struct ContractClassHint {
MSGPACK_FIELDS(artifactHash, privateFunctionsRoot, publicBytecodeCommitment, packedBytecode);
};

struct TreeRoots {
FF publicDataTree;
FF nullifierTree;
FF noteHashTree;
FF l1ToL2MessageTree;

bool operator==(const TreeRoots& other) const = default;

MSGPACK_FIELDS(publicDataTree, nullifierTree, noteHashTree, l1ToL2MessageTree);
};

struct ExecutionHints {
std::vector<ContractInstanceHint> contractInstances;
std::vector<ContractClassHint> contractClasses;
TreeRoots initialTreeRoots;

bool operator==(const ExecutionHints& other) const = default;

MSGPACK_FIELDS(contractInstances, contractClasses);
MSGPACK_FIELDS(contractInstances, contractClasses, initialTreeRoots);
};

struct PublicExecutionRequest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ TEST(AvmInputsTest, Deserialization)
.packedBytecode = string_to_buffer("secondbuffer"),
},
},
.initialTreeRoots = {
.publicDataTree = FF(0x1),
.nullifierTree = FF(0x2),
.noteHashTree = FF(0x3),
.l1ToL2MessageTree = FF(0x4),
},
},
};

Expand All @@ -115,6 +121,7 @@ TEST(AvmInputsTest, Deserialization)
EXPECT_EQ(inputs.publicInputs, expected.publicInputs);
EXPECT_EQ(inputs.hints.contractClasses, expected.hints.contractClasses);
EXPECT_EQ(inputs.hints.contractInstances, expected.hints.contractInstances);
EXPECT_EQ(inputs.hints.initialTreeRoots, expected.hints.initialTreeRoots);
EXPECT_EQ(inputs, expected); // Catch all.
}

Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ BytecodeId TxBytecodeManager::get_bytecode(const AztecAddress& address)
.address = address,
.siloed_address = address, // FIXME: compute, check.
.contract_instance = instance,
.contract_class = klass // WARNING: this class has the whole bytecode.
.contract_class = klass, // WARNING: this class has the whole bytecode.
.nullifier_root = db.get_tree_roots().nullifierTree,
});

return bytecode_id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct BytecodeRetrievalEvent {
AztecAddress siloed_address;
ContractInstance contract_instance;
ContractClass contract_class;
FF nullifier_root;
bool error = false;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace bb::avm2::simulation {
HintedRawDataDB::HintedRawDataDB(const ExecutionHints& hints)
: contract_instances(hints.contractInstances)
, contract_classes(hints.contractClasses)
, tree_roots(hints.initialTreeRoots)
{}

ContractInstance HintedRawDataDB::get_contract_instance(const AztecAddress& address) const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class RawDataDBInterface {

virtual ContractInstance get_contract_instance(const AztecAddress& address) const = 0;
virtual ContractClass get_contract_class(const ContractClassId& class_id) const = 0;
virtual const TreeRoots& get_tree_roots() const = 0;
};

class HintedRawDataDB : public RawDataDBInterface {
Expand All @@ -20,10 +21,12 @@ class HintedRawDataDB : public RawDataDBInterface {

ContractInstance get_contract_instance(const AztecAddress& address) const override;
ContractClass get_contract_class(const ContractClassId& class_id) const override;
const TreeRoots& get_tree_roots() const override { return tree_roots; }

private:
std::vector<ContractInstanceHint> contract_instances;
std::vector<ContractClassHint> contract_classes;
TreeRoots tree_roots;
mutable size_t contract_instances_idx = 0;
mutable size_t contract_classes_idx = 0;
};
Expand Down
8 changes: 7 additions & 1 deletion yarn-project/circuits.js/src/structs/avm/avm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ describe('Avm circuit inputs', () => {
packedBytecode: Buffer.from('secondbuffer'),
},
],
initialTreeRoots: {
publicDataTree: new Fr(1),
nullifierTree: new Fr(2),
noteHashTree: new Fr(3),
l1ToL2MessageTree: new Fr(4),
},
};

const enqueuedCalls = [
Expand Down Expand Up @@ -125,7 +131,7 @@ describe('Avm circuit inputs', () => {

// Run with AZTEC_GENERATE_TEST_DATA=1 to update test data
const path = 'barretenberg/cpp/src/barretenberg/vm2/common/avm_inputs.testdata.bin';
writeTestData(path, buffer);
writeTestData(path, buffer, /*raw=*/ true);

const expected = readTestData(path);
expect(buffer).toEqual(expected);
Expand Down
6 changes: 6 additions & 0 deletions yarn-project/circuits.js/src/structs/avm/avm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,12 @@ export class AvmCircuitInputs {
const hints = {
contractInstances: [] as any[],
contractClasses: [] as any[],
initialTreeRoots: {
publicDataTree: this.output.startTreeSnapshots.publicDataTree.root,
nullifierTree: this.output.startTreeSnapshots.nullifierTree.root,
noteHashTree: this.output.startTreeSnapshots.noteHashTree.root,
l1ToL2MessageTree: this.output.startTreeSnapshots.l1ToL2MessageTree.root,
},
};
const inputs = {
hints: hints,
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/foundation/src/testing/files/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import { fileURLToPath } from '../../url/index.js';
import { isGenerateTestDataEnabled } from '../test_data.js';

/** Writes the contents specified to the target file if test data generation is enabled. */
export function writeTestData(targetFileFromRepoRoot: string, contents: string | Buffer) {
export function writeTestData(targetFileFromRepoRoot: string, contents: string | Buffer, raw: boolean = false) {
if (!isGenerateTestDataEnabled()) {
return;
}
const targetFile = getPathToFile(targetFileFromRepoRoot);
const toWrite = typeof contents === 'string' ? contents : contents.toString('hex');
const toWrite = raw ? contents : typeof contents === 'string' ? contents : contents.toString('hex');
writeFileSync(targetFile, toWrite);
const logger = createConsoleLogger('aztec:testing:test_data');
logger(`Wrote test data to ${targetFile}`);
Expand Down

1 comment on commit 4d149be

@AztecBot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'C++ Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: 4d149be Previous: 5f3cffc Ratio
commit(t) 4028415386 ns/iter 3080222129 ns/iter 1.31
Goblin::merge(t) 166153934 ns/iter 133853433 ns/iter 1.24

This comment was automatically generated by workflow using github-action-benchmark.

CC: @ludamad @codygunton

Please sign in to comment.