Skip to content
Merged
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
96 changes: 80 additions & 16 deletions cpp/src/aztec3/circuits/kernel/private/.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,9 +480,6 @@ TEST(private_kernel_tests, test_basic_contract_deployment)
NT::fr(uint256_t(0x01071e9a23e0f7edULL, 0x5d77b35d1830fa3eULL, 0xc6ba3660bb1f0c0bULL, 0x2ef9f7f09867fd6eULL));
const NT::address tx_origin = msg_sender;

Composer constructor_composer = Composer("../barretenberg/cpp/srs_db/ignition");
DB db;

FunctionData<NT> function_data{
.function_selector = 1, // TODO: deduce this from the contract, somehow.
.is_private = true,
Expand All @@ -498,9 +495,48 @@ TEST(private_kernel_tests, test_basic_contract_deployment)
.is_contract_deployment = true,
};

std::shared_ptr<NT::VK> constructor_vk = constructor_composer.compute_verification_key();
NT::fr arg0 = 5;
NT::fr arg1 = 1;
NT::fr arg2 = 999;

Composer dummy_constructor_composer = Composer("../barretenberg/cpp/srs_db/ignition");
{
// Dummmy invokation, in order to derive the vk of this circuit

// We need to use _dummy_ contract_deployment_data first, because the _proper_ version of the
// contract_deployment_data will need to contain the constructor_vk_hash... but the constructor's vk can only be
// computed after the composer has composed the circuit!
ContractDeploymentData<NT> dummy_contract_deployment_data{
.constructor_vk_hash = 0, // dummy
.function_tree_root = 0, // TODO actually get this?
.contract_address_salt = contract_address_salt,
.portal_contract_address = new_portal_contract_address,
};

DB dummy_db;
NativeOracle dummy_constructor_oracle = NativeOracle(dummy_db,
new_contract_address,
function_data,
call_context,
dummy_contract_deployment_data,
msg_sender_private_key);
OracleWrapper dummy_constructor_oracle_wrapper =
OracleWrapper(dummy_constructor_composer, dummy_constructor_oracle);

FunctionExecutionContext dummy_constructor_ctx(dummy_constructor_composer, dummy_constructor_oracle_wrapper);

constructor(dummy_constructor_ctx, arg0, arg1, arg2);
}

// Now we can derive the vk:
std::shared_ptr<NT::VK> constructor_vk = dummy_constructor_composer.compute_verification_key();
auto constructor_vk_hash = stdlib::recursion::verification_key<CT::bn254>::compress_native(constructor_vk);

// Now, we can proceed with the proper (non-dummy) invokation of our constructor circuit:

Composer constructor_composer = Composer("../barretenberg/cpp/srs_db/ignition");
DB db;

ContractDeploymentData<NT> contract_deployment_data{
.constructor_vk_hash = constructor_vk_hash, // TODO actually get this?
.function_tree_root = 0, // TODO actually get this?
Expand All @@ -514,10 +550,6 @@ TEST(private_kernel_tests, test_basic_contract_deployment)

FunctionExecutionContext constructor_ctx(constructor_composer, constructor_oracle_wrapper);

auto arg0 = NT::fr(5);
auto arg1 = NT::fr(1);
auto arg2 = NT::fr(999);

OptionalPrivateCircuitPublicInputs<NT> opt_constructor_public_inputs =
constructor(constructor_ctx, arg0, arg1, arg2);

Expand Down Expand Up @@ -678,9 +710,6 @@ TEST(private_kernel_tests, test_native_basic_contract_deployment)
* convert it to native types, so that it can be fed into the kernel circuit.
*
*/
Composer constructor_composer = Composer("../barretenberg/cpp/srs_db/ignition");
DB db;

FunctionData<NT> function_data{
.function_selector = 1, // TODO: deduce this from the contract, somehow.
.is_private = true,
Expand All @@ -696,9 +725,48 @@ TEST(private_kernel_tests, test_native_basic_contract_deployment)
.is_contract_deployment = true,
};

std::shared_ptr<NT::VK> constructor_vk = constructor_composer.compute_verification_key();
NT::fr arg0 = 5;
NT::fr arg1 = 1;
NT::fr arg2 = 999;

Composer dummy_constructor_composer = Composer("../barretenberg/cpp/srs_db/ignition");
{
// Dummmy invokation, in order to derive the vk of this circuit

// We need to use _dummy_ contract_deployment_data first, because the _proper_ version of the
// contract_deployment_data will need to contain the constructor_vk_hash... but the constructor's vk can only be
// computed after the composer has composed the circuit!
ContractDeploymentData<NT> dummy_contract_deployment_data{
.constructor_vk_hash = 0, // dummy
.function_tree_root = 0, // TODO actually get this?
.contract_address_salt = contract_address_salt,
.portal_contract_address = new_portal_contract_address,
};

DB dummy_db;
NativeOracle dummy_constructor_oracle = NativeOracle(dummy_db,
new_contract_address,
function_data,
call_context,
dummy_contract_deployment_data,
msg_sender_private_key);
OracleWrapper dummy_constructor_oracle_wrapper =
OracleWrapper(dummy_constructor_composer, dummy_constructor_oracle);

FunctionExecutionContext dummy_constructor_ctx(dummy_constructor_composer, dummy_constructor_oracle_wrapper);

constructor(dummy_constructor_ctx, arg0, arg1, arg2);
}

// Now we can derive the vk:
std::shared_ptr<NT::VK> constructor_vk = dummy_constructor_composer.compute_verification_key();
auto constructor_vk_hash = stdlib::recursion::verification_key<CT::bn254>::compress_native(constructor_vk);

// Now, we can proceed with the proper (non-dummy) invokation of our constructor circuit:

Composer constructor_composer = Composer("../barretenberg/cpp/srs_db/ignition");
DB db;

ContractDeploymentData<NT> contract_deployment_data{
.constructor_vk_hash = constructor_vk_hash, // TODO actually get this?
.function_tree_root = 0, // TODO actually get this?
Expand All @@ -712,10 +780,6 @@ TEST(private_kernel_tests, test_native_basic_contract_deployment)

FunctionExecutionContext constructor_ctx(constructor_composer, constructor_oracle_wrapper);

auto arg0 = NT::fr(5);
auto arg1 = NT::fr(1);
auto arg2 = NT::fr(999);

OptionalPrivateCircuitPublicInputs<NT> opt_constructor_public_inputs =
constructor(constructor_ctx, arg0, arg1, arg2);

Expand Down
46 changes: 16 additions & 30 deletions cpp/src/aztec3/utils/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,42 +82,28 @@ template <size_t SIZE> NT::boolean is_array_empty(std::array<NT::fr, SIZE> const

/**
* Inserts the `source` array at the first zero-valued index of the `target` array.
* Ensures that all values after the first zero-valued index are zeros too.
* Fails if the `source` array is too large vs the remaining capacity of the `target` array.
* TODO: this is an awful mess and should be improved!
*/
template <size_t size_1, size_t size_2>
void push_array_to_array(std::array<NT::fr, size_1> const& source, std::array<NT::fr, size_2>& target)
{
// TODO: inefficient to get length this way within this function. Probably best to inline the checks that we need
// into the below loops directly.
NT::fr target_length = array_length(target);
NT::fr target_capacity = NT::fr(target.size());
const NT::fr overflow_capacity = target_capacity + 1;

// ASSERT(uint256_t(target_capacity.get_value()) + 1 >
// uint256_t(target_length.get_value()) + uint256_t(source_length.get_value()));

NT::fr j_ct = 0; // circuit-type index for the inner loop
NT::fr next_target_index = target_length;
for (size_t i = 0; i < source.size(); ++i) {
auto& s = source[i];

// Triangular loop:
for (size_t j = i; j < target.size() - source.size() + i + 1; ++j) {
auto& t = target[j];

NT::boolean at_next_index = j_ct == next_target_index;

t = at_next_index ? s : t;

j_ct++;
// Check if the `source` array is too large vs the remaining capacity of the `target` array
size_t source_size = static_cast<size_t>(uint256_t(array_length(source)));
size_t target_size = static_cast<size_t>(uint256_t(array_length(target)));
ASSERT(source_size <= size_2 - target_size);

// Ensure that there are no non-zero values in the `target` array after the first zero-valued index
for (size_t i = target_size; i < size_2; i++) {
ASSERT(target[i] == NT::fr(0));
}
// Copy the non-zero elements of the `source` array to the `target` array at the first zero-valued index
auto zero_index = target_size;
for (size_t i = 0; i < size_1; i++) {
if (source[i] != NT::fr(0)) {
target[zero_index] = source[i];
zero_index++;
}

next_target_index++;

ASSERT(next_target_index != overflow_capacity); //"push_array_to_array target array capacity exceeded"

j_ct = i + 1;
}
}

Expand Down