Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
dbs.cpp
Go to the documentation of this file.
2
3#include <cstdint>
4#include <vector>
5
14
15using namespace bb::avm2::simulation;
17using namespace bb::world_state;
18
20
31
39
41{
42 if (!contract_classes.contains(class_id)) {
43 return std::nullopt;
44 }
45 // Compute the actual bytecode commitment from the stored bytecode
46 const auto& klass = contract_classes.at(class_id);
47 return compute_public_bytecode_commitment(klass.packed_bytecode);
48}
50 [[maybe_unused]] const AztecAddress& address, [[maybe_unused]] const FunctionSelector& selector) const
51{
52 return std::nullopt;
53}
54
55void FuzzerContractDB::add_contracts(const ContractDeploymentData& contract_deployment_data)
56{
57 // Extract ContractClasses
58 for (const auto& log : contract_deployment_data.contract_class_logs) {
59 ContractClass klass = from_logs(log);
60 contract_classes[klass.id] = klass;
61 }
62
63 // Extract ContractInstances
64 for (const auto& log : contract_deployment_data.private_logs) {
66 AztecAddress contract_address = log.fields[2];
68 }
69}
70
72 const ContractClassWithCommitment& contract_class)
73{
74 // todo(ilyas): think of a nicer way without both map and vector
75 // Only push to vector if not already present, otherwise we get duplicates sent to the TS simulator
76 if (contract_classes.contains(class_id)) {
77 return;
78 }
79 auto klass = ContractClass{
80 .id = contract_class.id,
81 .artifact_hash = contract_class.artifact_hash,
82 .private_functions_root = contract_class.private_functions_root,
83 .packed_bytecode = contract_class.packed_bytecode,
84 };
85 contract_classes_vector.push_back(klass);
87}
88
90{
91 // todo(ilyas): think of a nicer way without both map and vector
92 if (contract_instances.contains(address)) {
93 return;
94 }
95 contract_instances[address] = contract_instance;
96 contract_instances_vector.push_back({ address, contract_instance });
97}
98
99// Based on fromLogs in yarn-project/protocol-contracts/src/class-registry/contract_class_published_event.ts
101{
102 // todo(ilyas): difference between log.emitted_length and log.fields.fields.length?
103 size_t offset = 1; // Tag field is at index 0 and we skip it
104 auto class_id = log.fields.fields[offset++];
105 [[maybe_unused]] auto version = static_cast<uint32_t>(log.fields.fields[offset++]);
106 auto artifact_hash = log.fields.fields[offset++];
107 auto private_functions_root = log.fields.fields[offset++];
108 // The remainder is packed_bytecode, the first element is the length
109 auto packed_bytecode_len = static_cast<uint32_t>(log.fields.fields[offset++]);
110 std::vector<uint8_t> packed_bytecode;
111 packed_bytecode.reserve(packed_bytecode_len);
112 for (size_t i = 0; i < packed_bytecode_len; ++i) {
113 // todo(ilyas): check that the bufferFromFields function in TS skips the first byte of each field's buffer
114 // (since it expects it to be zero?)
115 std::vector<uint8_t> f = to_buffer(log.fields.fields[offset + i]);
116 packed_bytecode.insert(packed_bytecode.end(), f.begin() + 1, f.end());
117 }
118
119 return ContractClass{
120 .id = class_id,
121 .artifact_hash = artifact_hash,
122 .private_functions_root = private_functions_root,
123 .packed_bytecode = packed_bytecode,
124 };
125}
126
127// Base on fromLogs in yarn-project/protocol-contracts/src/instance-registry/contract_instance_published_event.ts
129{
130 // We skip the following fields:
131 // - tag (index 0)
132 // - version (index 1)
133 // - contract address (index 2)
134 size_t offset = 3;
135 FF salt = log.fields[offset++];
136 FF contract_class_id = log.fields[offset++];
137 FF initialization_hash = log.fields[offset++];
138 PublicKeys public_keys = {
139 .nullifier_key = { log.fields[offset++], log.fields[offset++] },
140 .incoming_viewing_key = { log.fields[offset++], log.fields[offset++] },
141 .outgoing_viewing_key = { log.fields[offset++], log.fields[offset++] },
142 .tagging_key = { log.fields[offset++], log.fields[offset++] },
143 };
144 auto deployer = AztecAddress(log.fields[offset++]);
145 return ContractInstance{
146 .salt = salt,
147 .deployer = deployer,
148 .current_contract_class_id = contract_class_id,
149 .original_contract_class_id = contract_class_id,
150 .initialization_hash = initialization_hash,
151 .public_keys = public_keys,
152 };
153}
154
156{
159 .contract_instances = contract_instances,
160 });
161}
162
164{
165 if (!checkpoints.empty()) {
166 checkpoints.pop();
167 }
168}
169
171{
172 if (!checkpoints.empty()) {
173 contract_classes = std::move(checkpoints.top().contract_classes);
174 contract_instances = std::move(checkpoints.top().contract_instances);
175 checkpoints.pop();
176 }
177}
178
182
183// Static instance definition
185
187{
189 { simulation::MerkleTreeId::NULLIFIER_TREE, NULLIFIER_TREE_HEIGHT },
190 { simulation::MerkleTreeId::NOTE_HASH_TREE, NOTE_HASH_TREE_HEIGHT },
191 { simulation::MerkleTreeId::PUBLIC_DATA_TREE, PUBLIC_DATA_TREE_HEIGHT },
192 { simulation::MerkleTreeId::L1_TO_L2_MESSAGE_TREE, L1_TO_L2_MSG_TREE_HEIGHT },
193 { simulation::MerkleTreeId::ARCHIVE, ARCHIVE_HEIGHT },
194 };
196 { simulation::MerkleTreeId::NULLIFIER_TREE, 128 },
197 { simulation::MerkleTreeId::PUBLIC_DATA_TREE, 128 },
198 };
199 uint32_t initial_header_generator_point = 28; // GeneratorIndex.BLOCK_HASH
201 /*thread_pool_size=*/4, DATA_DIR, MAP_SIZE_KB, tree_heights, tree_prefill, initial_header_generator_point);
202
203 fork_ids.push(ws->create_fork(std::nullopt));
204}
205
207{
208 return WorldStateRevision{ .forkId = fork_ids.top(), .blockNumber = 0, .includeUncommitted = true };
209}
210
212{
213 auto fork_id = ws->create_fork(std::nullopt);
214 fork_ids.push(fork_id);
215 return WorldStateRevision{ .forkId = fork_id, .blockNumber = 0, .includeUncommitted = true };
216}
218{
219 // We keep the initial fork, so pop until only one remains
220 while (fork_ids.size() != 1) {
221 ws->delete_fork(fork_ids.top());
222 fork_ids.pop();
223 }
224}
226{
227 NullifierLeafValue contract_nullifier =
229 fuzz_info("Registering contract address in world state: ", contract_nullifier.nullifier);
230 auto fork_id = fork_ids.top();
231 ws->insert_indexed_leaves<NullifierLeafValue>(MerkleTreeId::NULLIFIER_TREE, { contract_nullifier }, fork_id);
232}
233
235{
236 if (fee_payer == 0) {
237 return;
238 }
239 FF fee_juice_balance_slot = Poseidon2::hash({ FEE_JUICE_BALANCES_SLOT, fee_payer });
240 FF leaf_slot = Poseidon2::hash({ DOM_SEP__PUBLIC_LEAF_INDEX, FF(FEE_JUICE_ADDRESS), fee_juice_balance_slot });
241
242 // Write to public data tree using current fork
243 auto fork_id = fork_ids.top();
244 ws->update_public_data(PublicDataLeafValue(leaf_slot, balance), fork_id);
245}
246
248{
249 auto fork_id = fork_ids.top();
250 ws->update_public_data(public_data, fork_id);
251}
252
253void FuzzerWorldStateManager::append_note_hashes(const std::vector<FF>& note_hashes)
254{
255 auto fork_id = fork_ids.top();
256
257 uint64_t padding_leaves = MAX_NOTE_HASHES_PER_TX - (note_hashes.size() % MAX_NOTE_HASHES_PER_TX);
258
259 ws->append_leaves(MerkleTreeId::NOTE_HASH_TREE, note_hashes, fork_id);
260 ws->append_leaves(MerkleTreeId::NOTE_HASH_TREE, std::vector<FF>(padding_leaves, FF(0)), fork_id);
261}
262
263} // namespace bb::avm2::fuzzer
#define fuzz_info(...)
Definition constants.hpp:51
std::shared_ptr< Napi::ThreadSafeFunction > instance
#define ARCHIVE_HEIGHT
#define L1_TO_L2_MSG_TREE_HEIGHT
#define FEE_JUICE_ADDRESS
#define NULLIFIER_TREE_HEIGHT
#define MAX_NOTE_HASHES_PER_TX
#define DOM_SEP__PUBLIC_LEAF_INDEX
#define FEE_JUICE_BALANCES_SLOT
#define CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS
#define NOTE_HASH_TREE_HEIGHT
#define PUBLIC_DATA_TREE_HEIGHT
std::optional< ContractClass > get_contract_class(const ContractClassId &class_id) const override
Definition dbs.cpp:32
void add_contracts(const ContractDeploymentData &contract_deployment_data) override
Definition dbs.cpp:55
void revert_checkpoint() override
Definition dbs.cpp:170
std::unordered_map< ContractClassId, ContractClass > contract_classes
Definition dbs.hpp:44
ContractClass from_logs(const ContractClassLog &log) const
Definition dbs.cpp:100
std::vector< std::pair< AztecAddress, ContractInstance > > contract_instances_vector
Definition dbs.hpp:49
std::optional< ContractInstance > get_contract_instance(const AztecAddress &address) const override
ContractDBInterface methods.
Definition dbs.cpp:24
std::vector< ContractClass > contract_classes_vector
Definition dbs.hpp:48
void commit_checkpoint() override
Definition dbs.cpp:163
void add_contract_class(const ContractClassId &class_id, const ContractClassWithCommitment &contract_class)
Definition dbs.cpp:71
void create_checkpoint() override
Definition dbs.cpp:155
std::optional< FF > get_bytecode_commitment(const ContractClassId &class_id) const override
Definition dbs.cpp:40
std::unordered_map< AztecAddress, ContractInstance > contract_instances
Definition dbs.hpp:45
void add_contract_instance(const AztecAddress &address, const ContractInstance &contract_instance)
Definition dbs.cpp:89
std::optional< std::string > get_debug_function_name(const AztecAddress &address, const FunctionSelector &selector) const override
Definition dbs.cpp:49
std::stack< Checkpoint > checkpoints
Definition dbs.hpp:55
static constexpr const char * DATA_DIR
Definition dbs.hpp:68
std::unique_ptr< world_state::WorldState > ws
Definition dbs.hpp:113
world_state::WorldStateRevision fork()
Definition dbs.cpp:211
void register_contract_address(const AztecAddress &contract_address)
Definition dbs.cpp:225
static constexpr uint64_t MAP_SIZE_KB
Definition dbs.hpp:69
void append_note_hashes(const std::vector< FF > &note_hashes)
Definition dbs.cpp:253
std::stack< uint64_t > fork_ids
Definition dbs.hpp:114
void write_fee_payer_balance(const AztecAddress &fee_payer, const FF &balance)
Definition dbs.cpp:234
static FuzzerWorldStateManager * instance
FuzzerWorldStateManager methods.
Definition dbs.hpp:109
world_state::WorldStateRevision get_current_revision() const
Definition dbs.cpp:206
void public_data_write(const bb::crypto::merkle_tree::PublicDataLeafValue &public_data)
Definition dbs.cpp:247
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
ssize_t offset
Definition engine.cpp:36
FF compute_public_bytecode_commitment(std::span< const uint8_t > bytecode)
::bb::crypto::merkle_tree::PublicDataLeafValue PublicDataLeafValue
Definition db.hpp:38
FF unconstrained_silo_nullifier(const AztecAddress &contract_address, const FF &nullifier)
Definition merkle.cpp:31
FF ContractClassId
FF FunctionSelector
AvmFlavorSettings::FF FF
Definition field.hpp:10
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::vector< uint8_t > to_buffer(T const &value)
ContractClassLogFields fields
std::vector< uint8_t > packed_bytecode
std::vector< PrivateLog > private_logs
std::vector< ContractClassLog > contract_class_logs
std::vector< FF > fields
AffinePoint nullifier_key
std::unordered_map< ContractClassId, ContractClass > contract_classes
Definition dbs.hpp:52