Skip to content

Commit 08ca61f

Browse files
committed
feat(avm)!: add immutables_hash member to get contract instance opcode
1 parent 9c8d4d8 commit 08ca61f

30 files changed

Lines changed: 258 additions & 85 deletions

File tree

avm-transpiler/src/transpile.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,7 @@ fn handle_get_contract_instance(
16341634
DEPLOYER,
16351635
CLASS_ID,
16361636
INIT_HASH,
1637+
IMMUTABLES_HASH,
16371638
}
16381639

16391640
assert_eq!(inputs.len(), 1);
@@ -1643,6 +1644,7 @@ fn handle_get_contract_instance(
16431644
"aztec_avm_getContractInstanceDeployer" => ContractInstanceMember::DEPLOYER,
16441645
"aztec_avm_getContractInstanceClassId" => ContractInstanceMember::CLASS_ID,
16451646
"aztec_avm_getContractInstanceInitializationHash" => ContractInstanceMember::INIT_HASH,
1647+
"aztec_avm_getContractInstanceImmutablesHash" => ContractInstanceMember::IMMUTABLES_HASH,
16461648
_ => panic!("Transpiler doesn't know how to process function {:?}", function),
16471649
};
16481650

barretenberg/cpp/pil/vm2/opcodes/get_contract_instance.pil

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,17 @@ include "../precomputed.pil";
1111
* - Bounds-check dst_offset+1 via #[WRITE_OUT_OF_BOUNDS_CHECK]. If dst_offset is the
1212
* maximum valid address, dst_offset+1 would be out of bounds.
1313
* - Look up member_enum in the precomputed table (#[PRECOMPUTED_INFO]) to determine
14-
* validity and which member is selected (deployer, class_id, or init_hash).
14+
* validity and which member is selected (deployer, class_id, init_hash or immutables_hash).
1515
* The precomputed table covers the full 8-bit range:
16-
* +-------+----------------------+-------------+-------------+--------------+
17-
* | idx | is_valid_member_enum | is_deployer | is_class_id | is_init_hash |
18-
* +-------+----------------------+-------------+-------------+--------------+
19-
* | 0 | 1 | 1 | 0 | 0 |
20-
* | 1 | 1 | 0 | 1 | 0 |
21-
* | 2 | 1 | 0 | 0 | 1 |
22-
* | 3+ | 0 | 0 | 0 | 0 |
23-
* +-------+----------------------+-------------+-------------+--------------+
16+
* +-------+----------------------+-------------+-------------+--------------+--------------------+
17+
* | idx | is_valid_member_enum | is_deployer | is_class_id | is_init_hash | is_immutables_hash |
18+
* +-------+----------------------+-------------+-------------+--------------+--------------------+
19+
* | 0 | 1 | 1 | 0 | 0 | 0 |
20+
* | 1 | 1 | 0 | 1 | 0 | 0 |
21+
* | 2 | 1 | 0 | 0 | 1 | 0 |
22+
* | 3 | 1 | 0 | 0 | 0 | 1 |
23+
* | 4+ | 0 | 0 | 0 | 0 | 0 |
24+
* +-------+----------------------+-------------+-------------+--------------+--------------------+
2425
* - Aggregate errors via #[ERROR_AGGREGATION]. sel_error is set when either
2526
* is_valid_writes_in_bounds or is_valid_member_enum is false.
2627
* - [no error only] Retrieve contract instance via the ContractInstanceRetrieval gadget
@@ -72,7 +73,7 @@ include "../precomputed.pil";
7273
* ERROR HANDLING:
7374
* Two error conditions, which are NOT mutually exclusive:
7475
* - Write out-of-bounds: dst_offset == AVM_HIGHEST_MEM_ADDRESS (dst_offset+1 overflows).
75-
* - Invalid member enum: member_enum >= 3 (precomputed table returns is_valid_member_enum=0).
76+
* - Invalid member enum: member_enum >= 4 (precomputed table returns is_valid_member_enum=0).
7677
* On error, the row has sel_error=1. The contract instance retrieval lookup and memory
7778
* write permutations are disabled (their selectors is_valid_member_enum / is_valid_writes_in_bounds
7879
* are 0), so no destination interactions fire for error rows.
@@ -121,13 +122,14 @@ namespace get_contract_instance;
121122
// (from precomputed.pil's GETCONTRACTINSTANCE opcode precomputed columns)
122123
// These are constrained only via the #[PRECOMPUTED_INFO] lookup when is_valid_writes_in_bounds == 1.
123124
// When the lookup is disabled (writes out of bounds), is_valid_member_enum is forced to 0 by
124-
// #[IS_VALID_MEMBER_ENUM_ONLY_SET_BY_PRECOMPUTED_LOOKUP]. is_deployer/is_class_id/is_init_hash
125+
// #[IS_VALID_MEMBER_ENUM_ONLY_SET_BY_PRECOMPUTED_LOOKUP]. is_deployer/is_class_id/is_init_hash/is_immutables_hash
125126
// are free in that case, but safe: they are only consumed in #[SELECTED_MEMBER] and the memory
126127
// write permutations, all of which are gated on is_valid_member_enum (which is 0).
127128
pol commit is_valid_member_enum; // @boolean (by lookup when is_valid_writes_in_bounds == 1)
128129
pol commit is_deployer; // @boolean (by lookup when is_valid_writes_in_bounds == 1)
129130
pol commit is_class_id; // @boolean (by lookup when is_valid_writes_in_bounds == 1)
130131
pol commit is_init_hash; // @boolean (by lookup when is_valid_writes_in_bounds == 1)
132+
pol commit is_immutables_hash; // @boolean (by lookup when is_valid_writes_in_bounds == 1)
131133
// Note: member_enum is guaranteed to be 8 bits by execution (as a U8 immediate operand),
132134
// and the precomputed table is populated for the entire 8-bit range (256 rows).
133135
#[PRECOMPUTED_INFO]
@@ -138,15 +140,17 @@ namespace get_contract_instance;
138140
is_valid_member_enum,
139141
is_deployer,
140142
is_class_id,
141-
is_init_hash
143+
is_init_hash,
144+
is_immutables_hash
142145
} in precomputed.sel_range_8 {
143146
// inputs
144147
precomputed.idx,
145148
// outputs
146149
precomputed.is_valid_member_enum,
147150
precomputed.is_deployer,
148151
precomputed.is_class_id,
149-
precomputed.is_init_hash
152+
precomputed.is_init_hash,
153+
precomputed.is_immutables_hash
150154
};
151155
// Do not allow is_valid_member_enum to be 1 if the precomputed lookup is disabled.
152156
#[IS_VALID_MEMBER_ENUM_ONLY_SET_BY_PRECOMPUTED_LOOKUP]
@@ -171,6 +175,7 @@ namespace get_contract_instance;
171175
pol commit retrieved_deployer_addr;
172176
pol commit retrieved_class_id;
173177
pol commit retrieved_init_hash;
178+
pol commit retrieved_immutables_hash;
174179

175180
#[CONTRACT_INSTANCE_RETRIEVAL]
176181
is_valid_member_enum {
@@ -182,7 +187,8 @@ namespace get_contract_instance;
182187
instance_exists,
183188
retrieved_deployer_addr,
184189
retrieved_class_id,
185-
retrieved_init_hash
190+
retrieved_init_hash,
191+
retrieved_immutables_hash
186192
} in contract_instance_retrieval.sel {
187193
// inputs
188194
contract_instance_retrieval.address,
@@ -192,14 +198,15 @@ namespace get_contract_instance;
192198
contract_instance_retrieval.exists,
193199
contract_instance_retrieval.deployer_addr,
194200
contract_instance_retrieval.current_class_id,
195-
contract_instance_retrieval.init_hash
201+
contract_instance_retrieval.init_hash,
202+
contract_instance_retrieval.immutables_hash
196203
};
197204

198205
// Select the member indicated by the enum for writing to memory
199206
// Note: is_* selectors are guaranteed to be mutually exclusive booleans by the precomputed table.
200207
pol commit selected_member;
201208
#[SELECTED_MEMBER]
202-
selected_member = is_deployer * retrieved_deployer_addr + is_class_id * retrieved_class_id + is_init_hash * retrieved_init_hash;
209+
selected_member = is_deployer * retrieved_deployer_addr + is_class_id * retrieved_class_id + is_init_hash * retrieved_init_hash + is_immutables_hash * retrieved_immutables_hash;
203210

204211
// Compute memory offsets for writing to
205212
pol commit member_write_offset;

barretenberg/cpp/pil/vm2/precomputed.pil

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ pol constant out_tag;
435435

436436
// ===== Section 14: GETCONTRACTINSTANCE opcode columns =====
437437
// Maps contract instance member enum values to selectors indicating which field
438-
// (deployer, class_id, init_hash) is being accessed.
438+
// (deployer, class_id, init_hash, immutables_hash) is being accessed.
439439
// Used by the GETCONTRACTINSTANCE opcode.
440440
//
441441
// see opcodes/get_contract_instance.pil for ascii table
@@ -444,3 +444,4 @@ pol constant is_valid_member_enum;
444444
pol constant is_deployer;
445445
pol constant is_class_id;
446446
pol constant is_init_hash;
447+
pol constant is_immutables_hash;

barretenberg/cpp/src/barretenberg/vm2/common/aztec_types.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ enum class ContractInstanceMember : uint8_t {
7777
DEPLOYER = 0,
7878
CLASS_ID = 1,
7979
INIT_HASH = 2,
80-
MAX = INIT_HASH,
80+
IMMUTABLES_HASH = 3,
81+
MAX = IMMUTABLES_HASH,
8182
};
8283

8384
////////////////////////////////////////////////////////////////////////////

barretenberg/cpp/src/barretenberg/vm2/constraining/avm_fixed_vk.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class AvmHardCodedVKAndHash {
1717
using FF = bb::curve::BN254::ScalarField;
1818

1919
// Precomputed VK hash (hash of all commitments below).
20-
static FF vk_hash() { return FF(uint256_t("0x23a03c6f87c465dbecc386b091e8123a8936597b5b0749f276d042a8964bd390")); }
20+
static FF vk_hash() { return FF(uint256_t("0x153c7fcc6b4d41c6e66f43b95aeea43979a734a1fc25edbc27ad30bf8462a192")); }
2121

2222
static constexpr std::array<Commitment, NUM_PRECOMPUTED_ENTITIES> get_all()
2323
{
@@ -134,6 +134,10 @@ class AvmHardCodedVKAndHash {
134134
uint256_t("0x0000000000000000000000000000000000000000000000000000000000000001"),
135135
uint256_t(
136136
"0x0000000000000000000000000000000000000000000000000000000000000002")), // precomputed_is_deployer
137+
Commitment(
138+
uint256_t("0x210bedcbb97a2e72905c082dd087be36c29c67e85b47de07b639e28a7dd78c76"),
139+
uint256_t(
140+
"0x18d1e431b83aa3ab2f6904bbbc452fee3472c01c0ceaf6d2fe6e37c4ff79e265")), // precomputed_is_immutables_hash
137141
Commitment(
138142
uint256_t("0x020ad6e43ccd48a6a39e43897cc85187bd364919be8a3b82d4809715cfe489db"),
139143
uint256_t(
@@ -171,9 +175,9 @@ class AvmHardCodedVKAndHash {
171175
uint256_t(
172176
"0x23268ad7678b97fba97cc3e75da6cff9a3659c3b8a49046cce4062820e5c1116")), // precomputed_is_tree_padding
173177
Commitment(
174-
uint256_t("0x210cdba7d0dae8d84cdd77a912060188657a0628905c0531fa63138ec3cbc9ea"),
178+
uint256_t("0x00c43726f75b6fda0de22ce0e0dfab6bcc7a05ff95a96b289424c5f733670d96"),
175179
uint256_t(
176-
"0x264f0d3eab260e5a20bdc5324e1ddcb3a0c0d811bb4a23b983417fd8c280486a")), // precomputed_is_valid_member_enum
180+
"0x2f9b6e0b4e2c01968de5c32482aa7d1d0a09d7178ec93bad7858f96e64f0b48d")), // precomputed_is_valid_member_enum
177181
Commitment(
178182
uint256_t("0x057e5478fbad129bb84bfb618f6e7a747812510b4f6f70bd84d4688f760ecb62"),
179183
uint256_t(

barretenberg/cpp/src/barretenberg/vm2/constraining/relations/get_contract_instance.test.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ TEST(GetContractInstanceConstrainingTest, SelectedMemberConstraint)
141141
const FF deployer_addr = 0x1234;
142142
const FF class_id = 0x5678;
143143
const FF init_hash = 0x9ABC;
144+
const FF immutables_hash = 0xCAFE;
144145
const FF wrong_value = 0x1111;
145146

146147
// Test selected member subrelation
@@ -152,9 +153,11 @@ TEST(GetContractInstanceConstrainingTest, SelectedMemberConstraint)
152153
{ C::get_contract_instance_is_deployer, 1 },
153154
{ C::get_contract_instance_is_class_id, 0 },
154155
{ C::get_contract_instance_is_init_hash, 0 },
156+
{ C::get_contract_instance_is_immutables_hash, 0 },
155157
{ C::get_contract_instance_retrieved_deployer_addr, deployer_addr },
156158
{ C::get_contract_instance_retrieved_class_id, class_id },
157-
{ C::get_contract_instance_retrieved_init_hash, init_hash } },
159+
{ C::get_contract_instance_retrieved_init_hash, init_hash },
160+
{ C::get_contract_instance_retrieved_immutables_hash, immutables_hash } },
158161
});
159162

160163
check_relation<get_contract_instance>(trace, get_contract_instance::SR_SELECTED_MEMBER);
@@ -171,6 +174,12 @@ TEST(GetContractInstanceConstrainingTest, SelectedMemberConstraint)
171174
trace.set(C::get_contract_instance_is_init_hash, 1, 1);
172175
check_relation<get_contract_instance>(trace, get_contract_instance::SR_SELECTED_MEMBER);
173176

177+
// Test IMMUTABLES_HASH selection
178+
trace.set(C::get_contract_instance_selected_member, 1, immutables_hash);
179+
trace.set(C::get_contract_instance_is_init_hash, 1, 0);
180+
trace.set(C::get_contract_instance_is_immutables_hash, 1, 1);
181+
check_relation<get_contract_instance>(trace, get_contract_instance::SR_SELECTED_MEMBER);
182+
174183
// Negative test: wrong selected member
175184
trace.set(C::get_contract_instance_selected_member, 1, wrong_value); // Wrong value
176185
EXPECT_THROW_WITH_MESSAGE(check_relation<get_contract_instance>(trace, get_contract_instance::SR_SELECTED_MEMBER),

barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp

Lines changed: 7 additions & 7 deletions
Large diffs are not rendered by default.

barretenberg/cpp/src/barretenberg/vm2/generated/flavor_variables.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@
140140
namespace bb::avm2 {
141141

142142
struct AvmFlavorVariables {
143-
static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 119;
144-
static constexpr size_t NUM_WITNESS_ENTITIES = 2958;
143+
static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 120;
144+
static constexpr size_t NUM_WITNESS_ENTITIES = 2960;
145145
static constexpr size_t NUM_SHIFTED_ENTITIES = 364;
146-
static constexpr size_t NUM_WIRES = 2514;
147-
static constexpr size_t NUM_ALL_ENTITIES = 3441;
146+
static constexpr size_t NUM_WIRES = 2516;
147+
static constexpr size_t NUM_ALL_ENTITIES = 3444;
148148

149149
// Need to be templated for recursive verifier
150150
template <typename FF_>

barretenberg/cpp/src/barretenberg/vm2/generated/relations/get_contract_instance_impl.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ void get_contract_instanceImpl<FF_>::accumulate(ContainerOverSubrelations& evals
7474
static_cast<View>(in.get(C::get_contract_instance_is_class_id)) *
7575
static_cast<View>(in.get(C::get_contract_instance_retrieved_class_id)) +
7676
static_cast<View>(in.get(C::get_contract_instance_is_init_hash)) *
77-
static_cast<View>(in.get(C::get_contract_instance_retrieved_init_hash))));
77+
static_cast<View>(in.get(C::get_contract_instance_retrieved_init_hash)) +
78+
static_cast<View>(in.get(C::get_contract_instance_is_immutables_hash)) *
79+
static_cast<View>(in.get(C::get_contract_instance_retrieved_immutables_hash))));
7880
std::get<6>(evals) += (tmp * scaling_factor);
7981
}
8082
{ // MEMBER_WRITE_OFFSET

barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_get_contract_instance.hpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace bb::avm2 {
1616
struct lookup_get_contract_instance_precomputed_info_settings_ {
1717
static constexpr std::string_view NAME = "LOOKUP_GET_CONTRACT_INSTANCE_PRECOMPUTED_INFO";
1818
static constexpr std::string_view RELATION_NAME = "get_contract_instance";
19-
static constexpr size_t LOOKUP_TUPLE_SIZE = 5;
19+
static constexpr size_t LOOKUP_TUPLE_SIZE = 6;
2020
static constexpr Column SRC_SELECTOR = Column::get_contract_instance_is_valid_writes_in_bounds;
2121
static constexpr Column DST_SELECTOR = Column::precomputed_sel_range_8;
2222
static constexpr Column COUNTS = Column::lookup_get_contract_instance_precomputed_info_counts;
@@ -26,14 +26,13 @@ struct lookup_get_contract_instance_precomputed_info_settings_ {
2626
ColumnAndShifts::get_contract_instance_is_valid_member_enum,
2727
ColumnAndShifts::get_contract_instance_is_deployer,
2828
ColumnAndShifts::get_contract_instance_is_class_id,
29-
ColumnAndShifts::get_contract_instance_is_init_hash
29+
ColumnAndShifts::get_contract_instance_is_init_hash,
30+
ColumnAndShifts::get_contract_instance_is_immutables_hash
3031
};
3132
static constexpr std::array<ColumnAndShifts, LOOKUP_TUPLE_SIZE> DST_COLUMNS = {
32-
ColumnAndShifts::precomputed_idx,
33-
ColumnAndShifts::precomputed_is_valid_member_enum,
34-
ColumnAndShifts::precomputed_is_deployer,
35-
ColumnAndShifts::precomputed_is_class_id,
36-
ColumnAndShifts::precomputed_is_init_hash
33+
ColumnAndShifts::precomputed_idx, ColumnAndShifts::precomputed_is_valid_member_enum,
34+
ColumnAndShifts::precomputed_is_deployer, ColumnAndShifts::precomputed_is_class_id,
35+
ColumnAndShifts::precomputed_is_init_hash, ColumnAndShifts::precomputed_is_immutables_hash
3736
};
3837
};
3938

@@ -48,7 +47,7 @@ using lookup_get_contract_instance_precomputed_info_relation =
4847
struct lookup_get_contract_instance_contract_instance_retrieval_settings_ {
4948
static constexpr std::string_view NAME = "LOOKUP_GET_CONTRACT_INSTANCE_CONTRACT_INSTANCE_RETRIEVAL";
5049
static constexpr std::string_view RELATION_NAME = "get_contract_instance";
51-
static constexpr size_t LOOKUP_TUPLE_SIZE = 7;
50+
static constexpr size_t LOOKUP_TUPLE_SIZE = 8;
5251
static constexpr Column SRC_SELECTOR = Column::get_contract_instance_is_valid_member_enum;
5352
static constexpr Column DST_SELECTOR = Column::contract_instance_retrieval_sel;
5453
static constexpr Column COUNTS = Column::lookup_get_contract_instance_contract_instance_retrieval_counts;
@@ -60,7 +59,8 @@ struct lookup_get_contract_instance_contract_instance_retrieval_settings_ {
6059
ColumnAndShifts::get_contract_instance_instance_exists,
6160
ColumnAndShifts::get_contract_instance_retrieved_deployer_addr,
6261
ColumnAndShifts::get_contract_instance_retrieved_class_id,
63-
ColumnAndShifts::get_contract_instance_retrieved_init_hash
62+
ColumnAndShifts::get_contract_instance_retrieved_init_hash,
63+
ColumnAndShifts::get_contract_instance_retrieved_immutables_hash
6464
};
6565
static constexpr std::array<ColumnAndShifts, LOOKUP_TUPLE_SIZE> DST_COLUMNS = {
6666
ColumnAndShifts::contract_instance_retrieval_address,
@@ -69,7 +69,8 @@ struct lookup_get_contract_instance_contract_instance_retrieval_settings_ {
6969
ColumnAndShifts::contract_instance_retrieval_exists,
7070
ColumnAndShifts::contract_instance_retrieval_deployer_addr,
7171
ColumnAndShifts::contract_instance_retrieval_current_class_id,
72-
ColumnAndShifts::contract_instance_retrieval_init_hash
72+
ColumnAndShifts::contract_instance_retrieval_init_hash,
73+
ColumnAndShifts::contract_instance_retrieval_immutables_hash
7374
};
7475
};
7576

0 commit comments

Comments
 (0)