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{
73 // todo(ilyas): think of a nicer way without both map and vector
74 // Only push to vector if not already present, otherwise we get duplicates sent to the TS simulator
75 if (contract_classes.contains(class_id)) {
76 return;
77 }
78 contract_classes_vector.push_back(contract_class);
79 contract_classes[class_id] = contract_class;
80}
81
83{
84 // todo(ilyas): think of a nicer way without both map and vector
85 if (contract_instances.contains(address)) {
86 return;
87 }
88 contract_instances[address] = contract_instance;
89 contract_instances_vector.push_back({ address, contract_instance });
90}
91
92// Based on fromLogs in yarn-project/protocol-contracts/src/class-registry/contract_class_published_event.ts
94{
95 // todo(ilyas): difference between log.emitted_length and log.fields.fields.length?
96 size_t offset = 1; // Tag field is at index 0 and we skip it
97 auto class_id = log.fields.fields[offset++];
98 [[maybe_unused]] auto version = static_cast<uint32_t>(log.fields.fields[offset++]);
99 auto artifact_hash = log.fields.fields[offset++];
100 auto private_functions_root = log.fields.fields[offset++];
101 // The remainder is packed_bytecode, the first element is the length
102 auto packed_bytecode_len = static_cast<uint32_t>(log.fields.fields[offset++]);
103 std::vector<uint8_t> packed_bytecode;
104 packed_bytecode.reserve(packed_bytecode_len);
105 for (size_t i = 0; i < packed_bytecode_len; ++i) {
106 // todo(ilyas): check that the bufferFromFields function in TS skips the first byte of each field's buffer
107 // (since it expects it to be zero?)
108 std::vector<uint8_t> f = to_buffer(log.fields.fields[offset + i]);
109 packed_bytecode.insert(packed_bytecode.end(), f.begin() + 1, f.end());
110 }
111
112 return ContractClass{
113 .id = class_id,
114 .artifact_hash = artifact_hash,
115 .private_functions_root = private_functions_root,
116 .packed_bytecode = packed_bytecode,
117 };
118}
119
120// Base on fromLogs in yarn-project/protocol-contracts/src/instance-registry/contract_instance_published_event.ts
122{
123 // We skip the following fields:
124 // - tag (index 0)
125 // - version (index 1)
126 // - contract address (index 2)
127 size_t offset = 3;
128 FF salt = log.fields[offset++];
129 FF contract_class_id = log.fields[offset++];
130 FF initialization_hash = log.fields[offset++];
131 PublicKeys public_keys = {
132 .nullifier_key = { log.fields[offset++], log.fields[offset++] },
133 .incoming_viewing_key = { log.fields[offset++], log.fields[offset++] },
134 .outgoing_viewing_key = { log.fields[offset++], log.fields[offset++] },
135 .tagging_key = { log.fields[offset++], log.fields[offset++] },
136 };
137 auto deployer = AztecAddress(log.fields[offset++]);
138 return ContractInstance{
139 .salt = salt,
140 .deployer = deployer,
141 .current_contract_class_id = contract_class_id,
142 .original_contract_class_id = contract_class_id,
143 .initialization_hash = initialization_hash,
144 .public_keys = public_keys,
145 };
146}
147
149{
152 .contract_instances = contract_instances,
153 });
154}
155
157{
158 if (!checkpoints.empty()) {
159 checkpoints.pop();
160 }
161}
162
164{
165 if (!checkpoints.empty()) {
166 contract_classes = std::move(checkpoints.top().contract_classes);
167 contract_instances = std::move(checkpoints.top().contract_instances);
168 checkpoints.pop();
169 }
170}
171
175
176// Static instance definition
178
180{
182 { simulation::MerkleTreeId::NULLIFIER_TREE, NULLIFIER_TREE_HEIGHT },
183 { simulation::MerkleTreeId::NOTE_HASH_TREE, NOTE_HASH_TREE_HEIGHT },
184 { simulation::MerkleTreeId::PUBLIC_DATA_TREE, PUBLIC_DATA_TREE_HEIGHT },
185 { simulation::MerkleTreeId::L1_TO_L2_MESSAGE_TREE, L1_TO_L2_MSG_TREE_HEIGHT },
186 { simulation::MerkleTreeId::ARCHIVE, ARCHIVE_HEIGHT },
187 };
189 { simulation::MerkleTreeId::NULLIFIER_TREE, 128 },
190 { simulation::MerkleTreeId::PUBLIC_DATA_TREE, 128 },
191 };
192 uint32_t initial_header_generator_point = 28; // GeneratorIndex.BLOCK_HASH
194 /*thread_pool_size=*/4, DATA_DIR, MAP_SIZE_KB, tree_heights, tree_prefill, initial_header_generator_point);
195
196 fork_ids.push(ws->create_fork(std::nullopt));
197}
198
200{
201 return WorldStateRevision{ .forkId = fork_ids.top(), .blockNumber = 0, .includeUncommitted = true };
202}
203
205{
206 auto fork_id = ws->create_fork(std::nullopt);
207 fork_ids.push(fork_id);
208 return WorldStateRevision{ .forkId = fork_id, .blockNumber = 0, .includeUncommitted = true };
209}
211{
212 // We keep the initial fork, so pop until only one remains
213 while (fork_ids.size() != 1) {
214 ws->delete_fork(fork_ids.top());
215 fork_ids.pop();
216 }
217}
219{
220 NullifierLeafValue contract_nullifier =
222 fuzz_info("Registering contract address in world state: ", contract_nullifier.nullifier);
223 auto fork_id = fork_ids.top();
224 ws->insert_indexed_leaves<NullifierLeafValue>(MerkleTreeId::NULLIFIER_TREE, { contract_nullifier }, fork_id);
225}
226
228{
229 if (fee_payer == 0) {
230 return;
231 }
232 FF fee_juice_balance_slot = Poseidon2::hash({ FEE_JUICE_BALANCES_SLOT, fee_payer });
233 FF leaf_slot = Poseidon2::hash({ DOM_SEP__PUBLIC_LEAF_INDEX, FF(FEE_JUICE_ADDRESS), fee_juice_balance_slot });
234
235 // Write to public data tree using current fork
236 auto fork_id = fork_ids.top();
237 ws->update_public_data(PublicDataLeafValue(leaf_slot, balance), fork_id);
238}
239
240} // 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 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:163
std::unordered_map< ContractClassId, ContractClass > contract_classes
Definition dbs.hpp:44
ContractClass from_logs(const ContractClassLog &log) const
Definition dbs.cpp:93
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:156
void create_checkpoint() override
Definition dbs.cpp:148
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_class(const ContractClassId &class_id, const ContractClass &contract_class)
Definition dbs.cpp:71
void add_contract_instance(const AztecAddress &address, const ContractInstance &contract_instance)
Definition dbs.cpp:82
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:111
world_state::WorldStateRevision fork()
Definition dbs.cpp:204
void register_contract_address(const AztecAddress &contract_address)
Definition dbs.cpp:218
static constexpr uint64_t MAP_SIZE_KB
Definition dbs.hpp:69
std::stack< uint64_t > fork_ids
Definition dbs.hpp:112
void write_fee_payer_balance(const AztecAddress &fee_payer, const FF &balance)
Definition dbs.cpp:227
static FuzzerWorldStateManager * instance
FuzzerWorldStateManager methods.
Definition dbs.hpp:107
world_state::WorldStateRevision get_current_revision() const
Definition dbs.cpp:199
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< 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