Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions avm-transpiler/src/transpile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1634,6 +1634,7 @@ fn handle_get_contract_instance(
DEPLOYER,
CLASS_ID,
INIT_HASH,
IMMUTABLES_HASH,
}

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

Expand Down
39 changes: 23 additions & 16 deletions barretenberg/cpp/pil/vm2/opcodes/get_contract_instance.pil
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ include "../precomputed.pil";
* - Bounds-check dst_offset+1 via #[WRITE_OUT_OF_BOUNDS_CHECK]. If dst_offset is the
* maximum valid address, dst_offset+1 would be out of bounds.
* - Look up member_enum in the precomputed table (#[PRECOMPUTED_INFO]) to determine
* validity and which member is selected (deployer, class_id, or init_hash).
* validity and which member is selected (deployer, class_id, init_hash or immutables_hash).
* The precomputed table covers the full 8-bit range:
* +-------+----------------------+-------------+-------------+--------------+
* | idx | is_valid_member_enum | is_deployer | is_class_id | is_init_hash |
* +-------+----------------------+-------------+-------------+--------------+
* | 0 | 1 | 1 | 0 | 0 |
* | 1 | 1 | 0 | 1 | 0 |
* | 2 | 1 | 0 | 0 | 1 |
* | 3+ | 0 | 0 | 0 | 0 |
* +-------+----------------------+-------------+-------------+--------------+
* +-------+----------------------+-------------+-------------+--------------+--------------------+
* | idx | is_valid_member_enum | is_deployer | is_class_id | is_init_hash | is_immutables_hash |
* +-------+----------------------+-------------+-------------+--------------+--------------------+
* | 0 | 1 | 1 | 0 | 0 | 0 |
* | 1 | 1 | 0 | 1 | 0 | 0 |
* | 2 | 1 | 0 | 0 | 1 | 0 |
* | 3 | 1 | 0 | 0 | 0 | 1 |
* | 4+ | 0 | 0 | 0 | 0 | 0 |
* +-------+----------------------+-------------+-------------+--------------+--------------------+
* - Aggregate errors via #[ERROR_AGGREGATION]. sel_error is set when either
* is_valid_writes_in_bounds or is_valid_member_enum is false.
* - [no error only] Retrieve contract instance via the ContractInstanceRetrieval gadget
Expand Down Expand Up @@ -72,7 +73,7 @@ include "../precomputed.pil";
* ERROR HANDLING:
* Two error conditions, which are NOT mutually exclusive:
* - Write out-of-bounds: dst_offset == AVM_HIGHEST_MEM_ADDRESS (dst_offset+1 overflows).
* - Invalid member enum: member_enum >= 3 (precomputed table returns is_valid_member_enum=0).
* - Invalid member enum: member_enum >= 4 (precomputed table returns is_valid_member_enum=0).
* On error, the row has sel_error=1. The contract instance retrieval lookup and memory
* write permutations are disabled (their selectors is_valid_member_enum / is_valid_writes_in_bounds
* are 0), so no destination interactions fire for error rows.
Expand Down Expand Up @@ -121,13 +122,14 @@ namespace get_contract_instance;
// (from precomputed.pil's GETCONTRACTINSTANCE opcode precomputed columns)
// These are constrained only via the #[PRECOMPUTED_INFO] lookup when is_valid_writes_in_bounds == 1.
// When the lookup is disabled (writes out of bounds), is_valid_member_enum is forced to 0 by
// #[IS_VALID_MEMBER_ENUM_ONLY_SET_BY_PRECOMPUTED_LOOKUP]. is_deployer/is_class_id/is_init_hash
// #[IS_VALID_MEMBER_ENUM_ONLY_SET_BY_PRECOMPUTED_LOOKUP]. is_deployer/is_class_id/is_init_hash/is_immutables_hash
// are free in that case, but safe: they are only consumed in #[SELECTED_MEMBER] and the memory
// write permutations, all of which are gated on is_valid_member_enum (which is 0).
pol commit is_valid_member_enum; // @boolean (by lookup when is_valid_writes_in_bounds == 1)
pol commit is_deployer; // @boolean (by lookup when is_valid_writes_in_bounds == 1)
pol commit is_class_id; // @boolean (by lookup when is_valid_writes_in_bounds == 1)
pol commit is_init_hash; // @boolean (by lookup when is_valid_writes_in_bounds == 1)
pol commit is_immutables_hash; // @boolean (by lookup when is_valid_writes_in_bounds == 1)
// Note: member_enum is guaranteed to be 8 bits by execution (as a U8 immediate operand),
// and the precomputed table is populated for the entire 8-bit range (256 rows).
#[PRECOMPUTED_INFO]
Expand All @@ -138,15 +140,17 @@ namespace get_contract_instance;
is_valid_member_enum,
is_deployer,
is_class_id,
is_init_hash
is_init_hash,
is_immutables_hash
} in precomputed.sel_range_8 {
// inputs
precomputed.idx,
// outputs
precomputed.is_valid_member_enum,
precomputed.is_deployer,
precomputed.is_class_id,
precomputed.is_init_hash
precomputed.is_init_hash,
precomputed.is_immutables_hash
};
// Do not allow is_valid_member_enum to be 1 if the precomputed lookup is disabled.
#[IS_VALID_MEMBER_ENUM_ONLY_SET_BY_PRECOMPUTED_LOOKUP]
Expand All @@ -171,6 +175,7 @@ namespace get_contract_instance;
pol commit retrieved_deployer_addr;
pol commit retrieved_class_id;
pol commit retrieved_init_hash;
pol commit retrieved_immutables_hash;

#[CONTRACT_INSTANCE_RETRIEVAL]
is_valid_member_enum {
Expand All @@ -182,7 +187,8 @@ namespace get_contract_instance;
instance_exists,
retrieved_deployer_addr,
retrieved_class_id,
retrieved_init_hash
retrieved_init_hash,
retrieved_immutables_hash
} in contract_instance_retrieval.sel {
// inputs
contract_instance_retrieval.address,
Expand All @@ -192,14 +198,15 @@ namespace get_contract_instance;
contract_instance_retrieval.exists,
contract_instance_retrieval.deployer_addr,
contract_instance_retrieval.current_class_id,
contract_instance_retrieval.init_hash
contract_instance_retrieval.init_hash,
contract_instance_retrieval.immutables_hash
};

// Select the member indicated by the enum for writing to memory
// Note: is_* selectors are guaranteed to be mutually exclusive booleans by the precomputed table.
pol commit selected_member;
#[SELECTED_MEMBER]
selected_member = is_deployer * retrieved_deployer_addr + is_class_id * retrieved_class_id + is_init_hash * retrieved_init_hash;
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;

// Compute memory offsets for writing to
pol commit member_write_offset;
Expand Down
3 changes: 2 additions & 1 deletion barretenberg/cpp/pil/vm2/precomputed.pil
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ pol constant out_tag;

// ===== Section 14: GETCONTRACTINSTANCE opcode columns =====
// Maps contract instance member enum values to selectors indicating which field
// (deployer, class_id, init_hash) is being accessed.
// (deployer, class_id, init_hash, immutables_hash) is being accessed.
// Used by the GETCONTRACTINSTANCE opcode.
//
// see opcodes/get_contract_instance.pil for ascii table
Expand All @@ -444,3 +444,4 @@ pol constant is_valid_member_enum;
pol constant is_deployer;
pol constant is_class_id;
pol constant is_init_hash;
pol constant is_immutables_hash;
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ enum class ContractInstanceMember : uint8_t {
DEPLOYER = 0,
CLASS_ID = 1,
INIT_HASH = 2,
MAX = INIT_HASH,
IMMUTABLES_HASH = 3,
MAX = IMMUTABLES_HASH,
};

////////////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class AvmHardCodedVKAndHash {
using FF = bb::curve::BN254::ScalarField;

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

static constexpr std::array<Commitment, NUM_PRECOMPUTED_ENTITIES> get_all()
{
Expand Down Expand Up @@ -134,6 +134,10 @@ class AvmHardCodedVKAndHash {
uint256_t("0x0000000000000000000000000000000000000000000000000000000000000001"),
uint256_t(
"0x0000000000000000000000000000000000000000000000000000000000000002")), // precomputed_is_deployer
Commitment(
uint256_t("0x210bedcbb97a2e72905c082dd087be36c29c67e85b47de07b639e28a7dd78c76"),
uint256_t(
"0x18d1e431b83aa3ab2f6904bbbc452fee3472c01c0ceaf6d2fe6e37c4ff79e265")), // precomputed_is_immutables_hash
Commitment(
uint256_t("0x020ad6e43ccd48a6a39e43897cc85187bd364919be8a3b82d4809715cfe489db"),
uint256_t(
Expand Down Expand Up @@ -171,9 +175,9 @@ class AvmHardCodedVKAndHash {
uint256_t(
"0x23268ad7678b97fba97cc3e75da6cff9a3659c3b8a49046cce4062820e5c1116")), // precomputed_is_tree_padding
Commitment(
uint256_t("0x210cdba7d0dae8d84cdd77a912060188657a0628905c0531fa63138ec3cbc9ea"),
uint256_t("0x00c43726f75b6fda0de22ce0e0dfab6bcc7a05ff95a96b289424c5f733670d96"),
uint256_t(
"0x264f0d3eab260e5a20bdc5324e1ddcb3a0c0d811bb4a23b983417fd8c280486a")), // precomputed_is_valid_member_enum
"0x2f9b6e0b4e2c01968de5c32482aa7d1d0a09d7178ec93bad7858f96e64f0b48d")), // precomputed_is_valid_member_enum
Commitment(
uint256_t("0x057e5478fbad129bb84bfb618f6e7a747812510b4f6f70bd84d4688f760ecb62"),
uint256_t(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ TEST(GetContractInstanceConstrainingTest, SelectedMemberConstraint)
const FF deployer_addr = 0x1234;
const FF class_id = 0x5678;
const FF init_hash = 0x9ABC;
const FF immutables_hash = 0xCAFE;
const FF wrong_value = 0x1111;

// Test selected member subrelation
Expand All @@ -152,9 +153,11 @@ TEST(GetContractInstanceConstrainingTest, SelectedMemberConstraint)
{ C::get_contract_instance_is_deployer, 1 },
{ C::get_contract_instance_is_class_id, 0 },
{ C::get_contract_instance_is_init_hash, 0 },
{ C::get_contract_instance_is_immutables_hash, 0 },
{ C::get_contract_instance_retrieved_deployer_addr, deployer_addr },
{ C::get_contract_instance_retrieved_class_id, class_id },
{ C::get_contract_instance_retrieved_init_hash, init_hash } },
{ C::get_contract_instance_retrieved_init_hash, init_hash },
{ C::get_contract_instance_retrieved_immutables_hash, immutables_hash } },
});

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

// Test IMMUTABLES_HASH selection
trace.set(C::get_contract_instance_selected_member, 1, immutables_hash);
trace.set(C::get_contract_instance_is_init_hash, 1, 0);
trace.set(C::get_contract_instance_is_immutables_hash, 1, 1);
check_relation<get_contract_instance>(trace, get_contract_instance::SR_SELECTED_MEMBER);

// Negative test: wrong selected member
trace.set(C::get_contract_instance_selected_member, 1, wrong_value); // Wrong value
EXPECT_THROW_WITH_MESSAGE(check_relation<get_contract_instance>(trace, get_contract_instance::SR_SELECTED_MEMBER),
Expand Down
14 changes: 7 additions & 7 deletions barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@
namespace bb::avm2 {

struct AvmFlavorVariables {
static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 119;
static constexpr size_t NUM_WITNESS_ENTITIES = 2958;
static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 120;
static constexpr size_t NUM_WITNESS_ENTITIES = 2960;
static constexpr size_t NUM_SHIFTED_ENTITIES = 364;
static constexpr size_t NUM_WIRES = 2514;
static constexpr size_t NUM_ALL_ENTITIES = 3441;
static constexpr size_t NUM_WIRES = 2516;
static constexpr size_t NUM_ALL_ENTITIES = 3444;

// Need to be templated for recursive verifier
template <typename FF_>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ void get_contract_instanceImpl<FF_>::accumulate(ContainerOverSubrelations& evals
static_cast<View>(in.get(C::get_contract_instance_is_class_id)) *
static_cast<View>(in.get(C::get_contract_instance_retrieved_class_id)) +
static_cast<View>(in.get(C::get_contract_instance_is_init_hash)) *
static_cast<View>(in.get(C::get_contract_instance_retrieved_init_hash))));
static_cast<View>(in.get(C::get_contract_instance_retrieved_init_hash)) +
static_cast<View>(in.get(C::get_contract_instance_is_immutables_hash)) *
static_cast<View>(in.get(C::get_contract_instance_retrieved_immutables_hash))));
std::get<6>(evals) += (tmp * scaling_factor);
}
{ // MEMBER_WRITE_OFFSET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace bb::avm2 {
struct lookup_get_contract_instance_precomputed_info_settings_ {
static constexpr std::string_view NAME = "LOOKUP_GET_CONTRACT_INSTANCE_PRECOMPUTED_INFO";
static constexpr std::string_view RELATION_NAME = "get_contract_instance";
static constexpr size_t LOOKUP_TUPLE_SIZE = 5;
static constexpr size_t LOOKUP_TUPLE_SIZE = 6;
static constexpr Column SRC_SELECTOR = Column::get_contract_instance_is_valid_writes_in_bounds;
static constexpr Column DST_SELECTOR = Column::precomputed_sel_range_8;
static constexpr Column COUNTS = Column::lookup_get_contract_instance_precomputed_info_counts;
Expand All @@ -26,14 +26,13 @@ struct lookup_get_contract_instance_precomputed_info_settings_ {
ColumnAndShifts::get_contract_instance_is_valid_member_enum,
ColumnAndShifts::get_contract_instance_is_deployer,
ColumnAndShifts::get_contract_instance_is_class_id,
ColumnAndShifts::get_contract_instance_is_init_hash
ColumnAndShifts::get_contract_instance_is_init_hash,
ColumnAndShifts::get_contract_instance_is_immutables_hash
};
static constexpr std::array<ColumnAndShifts, LOOKUP_TUPLE_SIZE> DST_COLUMNS = {
ColumnAndShifts::precomputed_idx,
ColumnAndShifts::precomputed_is_valid_member_enum,
ColumnAndShifts::precomputed_is_deployer,
ColumnAndShifts::precomputed_is_class_id,
ColumnAndShifts::precomputed_is_init_hash
ColumnAndShifts::precomputed_idx, ColumnAndShifts::precomputed_is_valid_member_enum,
ColumnAndShifts::precomputed_is_deployer, ColumnAndShifts::precomputed_is_class_id,
ColumnAndShifts::precomputed_is_init_hash, ColumnAndShifts::precomputed_is_immutables_hash
};
};

Expand All @@ -48,7 +47,7 @@ using lookup_get_contract_instance_precomputed_info_relation =
struct lookup_get_contract_instance_contract_instance_retrieval_settings_ {
static constexpr std::string_view NAME = "LOOKUP_GET_CONTRACT_INSTANCE_CONTRACT_INSTANCE_RETRIEVAL";
static constexpr std::string_view RELATION_NAME = "get_contract_instance";
static constexpr size_t LOOKUP_TUPLE_SIZE = 7;
static constexpr size_t LOOKUP_TUPLE_SIZE = 8;
static constexpr Column SRC_SELECTOR = Column::get_contract_instance_is_valid_member_enum;
static constexpr Column DST_SELECTOR = Column::contract_instance_retrieval_sel;
static constexpr Column COUNTS = Column::lookup_get_contract_instance_contract_instance_retrieval_counts;
Expand All @@ -60,7 +59,8 @@ struct lookup_get_contract_instance_contract_instance_retrieval_settings_ {
ColumnAndShifts::get_contract_instance_instance_exists,
ColumnAndShifts::get_contract_instance_retrieved_deployer_addr,
ColumnAndShifts::get_contract_instance_retrieved_class_id,
ColumnAndShifts::get_contract_instance_retrieved_init_hash
ColumnAndShifts::get_contract_instance_retrieved_init_hash,
ColumnAndShifts::get_contract_instance_retrieved_immutables_hash
};
static constexpr std::array<ColumnAndShifts, LOOKUP_TUPLE_SIZE> DST_COLUMNS = {
ColumnAndShifts::contract_instance_retrieval_address,
Expand All @@ -69,7 +69,8 @@ struct lookup_get_contract_instance_contract_instance_retrieval_settings_ {
ColumnAndShifts::contract_instance_retrieval_exists,
ColumnAndShifts::contract_instance_retrieval_deployer_addr,
ColumnAndShifts::contract_instance_retrieval_current_class_id,
ColumnAndShifts::contract_instance_retrieval_init_hash
ColumnAndShifts::contract_instance_retrieval_init_hash,
ColumnAndShifts::contract_instance_retrieval_immutables_hash
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ struct GetContractInstanceEvent {
FF nullifier_tree_root = 0;
FF public_data_tree_root = 0;

// Instance retrieval results including all three members which are all needed for tracegen
// Instance retrieval results including all four members which are all needed for tracegen
// despite only needing the selected member in simulation.
bool instance_exists = false;
FF retrieved_deployer_addr = 0;
FF retrieved_class_id = 0;
FF retrieved_init_hash = 0;
FF retrieved_immutables_hash = 0;
};

} // namespace bb::avm2::simulation
Loading
Loading