Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
contract_instance_manager.cpp
Go to the documentation of this file.
2
3#include "barretenberg/aztec/aztec_constants.hpp"
5
6namespace bb::avm2::simulation {
7
31
49{
50 // If the instance is found, we validate that with a nullifier check, perform address derivation, and update
51 // checking. If it is not found, we validate its NON-membership with a nullifier check, and skip the rest.
52 // Note: this call to get_contract_instance performs address derivation.
53 std::optional<ContractInstance> maybe_instance = contract_db.get_contract_instance(contract_address);
54
55 const auto& tree_state = merkle_db.get_tree_state();
56
57 // Check if this is a protocol contract address (addresses 1 to MAX_PROTOCOL_CONTRACTS).
58 // Protocol contracts are special reserved addresses that don't require nullifier checks.
59 if (ff_gt.ff_gt(MAX_PROTOCOL_CONTRACTS, contract_address - 1)) {
60 // Handle protocol contract addresses.
61 // The derived_address lookup returns nullopt if this protocol contract slot is empty.
62 // NOTE: MAX_PROTOCOL_CONTRACTS (currently 11) is the reserved capacity, but not all
63 // slots may be filled. For example, addresses 1-6 are currently used while 7-11 are
64 // empty (reserved for future protocol contracts).
65 std::optional<AztecAddress> derived_address = get_derived_address(protocol_contracts, contract_address);
66
67 // Sanity check: if we found a derived address, we should also have the instance, and vice versa.
68 BB_ASSERT_EQ(derived_address.has_value(),
69 maybe_instance.has_value(),
70 "Derived address should be found if the instance was retrieved and vice versa");
71
72 BB_ASSERT_EQ(maybe_instance.value_or(ContractInstance()).current_contract_class_id,
73 maybe_instance.value_or(ContractInstance()).original_contract_class_id,
74 "Protocol contracts must have a matching current and original class ID");
75
76 event_emitter.emit({
77 .address = contract_address,
78 .contract_instance = maybe_instance.value_or(ContractInstance{}),
79 .nullifier_tree_root = tree_state.nullifier_tree.tree.root,
80 .public_data_tree_root = tree_state.public_data_tree.tree.root,
81 .exists = derived_address.has_value(),
82 .is_protocol_contract = true,
83 });
84 return maybe_instance;
85 }
86
87 if (!merkle_db.nullifier_exists(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS, contract_address)) {
88 // Emit error event
89 event_emitter.emit({
90 .address = contract_address,
91 .contract_instance = {}, // Empty instance for error case
92 .nullifier_tree_root = tree_state.nullifier_tree.tree.root,
93 .public_data_tree_root = tree_state.public_data_tree.tree.root,
94 .deployment_nullifier = contract_address,
95 .exists = false, // Nullifier not found!
96 });
97
98 return std::nullopt;
99 }
100
101 BB_ASSERT(maybe_instance.has_value(), "Contract instance should be found if nullifier exists");
102 const ContractInstance& instance = maybe_instance.value();
103
104 // Validate that the contract instance is the latest if there have been any updates.
105 update_check.check_current_class_id(contract_address, instance);
106
107 event_emitter.emit({
108 .address = contract_address,
109 .contract_instance = instance,
110 // Tree context
111 .nullifier_tree_root = tree_state.nullifier_tree.tree.root,
112 .public_data_tree_root = tree_state.public_data_tree.tree.root,
113 .deployment_nullifier = contract_address, // Contract address nullifier
114 .exists = true, // Nullifier found!
115 });
116
117 return instance;
118}
119
120} // namespace bb::avm2::simulation
#define BB_ASSERT(expression,...)
Definition assert.hpp:70
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:83
StrictMock< MockHighLevelMerkleDB > merkle_db
StrictMock< MockContractDB > contract_db
virtual std::optional< ContractInstance > get_contract_instance(const AztecAddress &address) const =0
ContractInstanceManager(ContractDBInterface &contract_db, HighLevelMerkleDBInterface &merkle_db, UpdateCheckInterface &update_check, FieldGreaterThanInterface &ff_gt, const ProtocolContracts &protocol_contracts, EventEmitterInterface< ContractInstanceRetrievalEvent > &event_emitter)
Construct a ContractInstanceManager.
std::optional< ContractInstance > get_contract_instance(const FF &contract_address) override
Retrieves a contract instance from the contract database.
EventEmitterInterface< ContractInstanceRetrievalEvent > & event_emitter
virtual bool nullifier_exists(const AztecAddress &contract_address, const FF &nullifier) const =0
virtual TreeStates get_tree_state() const =0
EventEmitter< DataCopyEvent > event_emitter
AVM range check gadget for witness generation.
AvmFlavorSettings::FF FF
Definition field.hpp:10
std::optional< AztecAddress > get_derived_address(const ProtocolContracts &protocol_contracts, const AztecAddress &canonical_address)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13