Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
## Overview
Works around brillig blowup issue by altering the read and write opcodes
to take in arrays of data. This is potentially just a short term fix.

- Reading and writing to storage now take in arrays, code will not
compile without this change, due to an ssa issue ->[ ISSUE
](AztecProtocol/aztec-packages#4979)

- Tag checks on memory now just make sure the tag is LESS than uint64,
rather than asserting that the memory tag is uint32, this should be
fine.

- We had to blow up the memory space of the avm to u64 as the entire
noir compiler works with u64s. Arrays will not work unless we either
    - Make the avm 64 bit addressable ( probably fine )
- Make noir 32 bit addressable ( requires alot of buy in )
AztecProtocol/aztec-packages#4814

---------

Co-authored-by: sirasistant <[email protected]>
  • Loading branch information
AztecBot and sirasistant committed Mar 7, 2024
1 parent fe8f277 commit 699f43d
Show file tree
Hide file tree
Showing 18 changed files with 433 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .aztec-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7ff9b71d8d87fc93ae7dbd8ba63f5176b0cd17be
fe3190ee66d5c340b6ef6a6fe53772e8e08c9463
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ members = [
"tooling/nargo_toml",
"tooling/noirc_abi",
"tooling/noirc_abi_wasm",
"tooling/acvm_cli",
# ACVM
"acvm-repo/acir_field",
"acvm-repo/acir",
Expand All @@ -36,7 +37,7 @@ members = [
"acvm-repo/blackbox_solver",
"acvm-repo/bn254_blackbox_solver",
]
default-members = ["tooling/nargo_cli"]
default-members = ["tooling/nargo_cli", "tooling/acvm_cli"]
resolver = "2"

[workspace.package]
Expand Down Expand Up @@ -78,6 +79,7 @@ noir_lsp = { path = "tooling/lsp" }
noir_debugger = { path = "tooling/debugger" }
noirc_abi = { path = "tooling/noirc_abi" }
bb_abstraction_leaks = { path = "tooling/bb_abstraction_leaks" }
acvm_cli = { path = "tooling/acvm_cli" }

# LSP
async-lsp = { version = "0.1.0", default-features = false }
Expand Down
8 changes: 7 additions & 1 deletion aztec_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -727,8 +727,14 @@ fn transform_function(
/// Transform a function to work with AVM bytecode
fn transform_vm_function(
func: &mut NoirFunction,
_storage_defined: bool,
storage_defined: bool,
) -> Result<(), AztecMacroError> {
// Create access to storage
if storage_defined {
let storage = abstract_storage("public_vm", true);
func.def.body.0.insert(0, storage);
}

// Push Avm context creation to the beginning of the function
let create_context = create_avm_context()?;
func.def.body.0.insert(0, create_context);
Expand Down
22 changes: 22 additions & 0 deletions bootstrap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -eu

cd $(dirname "$0")

CMD=${1:-}

if [ -n "$CMD" ]; then
if [ "$CMD" = "clean" ]; then
git clean -fdx
exit 0
else
echo "Unknown command: $CMD"
exit 1
fi
fi

# Attempt to just pull artefacts from CI and exit on success.
[ -n "${USE_CACHE:-}" ] && ./bootstrap_cache.sh && exit

./scripts/bootstrap_native.sh
./scripts/bootstrap_packages.sh
13 changes: 13 additions & 0 deletions bootstrap_cache.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -eu

cd "$(dirname "$0")"
source ../build-system/scripts/setup_env '' '' mainframe_$USER > /dev/null

echo -e "\033[1mRetrieving noir packages from remote cache...\033[0m"
extract_repo noir-packages /usr/src/noir/packages ./
echo -e "\033[1mRetrieving nargo from remote cache...\033[0m"
extract_repo noir /usr/src/noir/target/release ./target/

remove_old_images noir-packages
remove_old_images noir
3 changes: 2 additions & 1 deletion compiler/noirc_evaluator/src/brillig/brillig_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use num_bigint::BigUint;
/// The Brillig VM does not apply a limit to the memory address space,
/// As a convention, we take use 64 bits. This means that we assume that
/// memory has 2^64 memory slots.
pub(crate) const BRILLIG_MEMORY_ADDRESSING_BIT_SIZE: u32 = 32;
pub(crate) const BRILLIG_MEMORY_ADDRESSING_BIT_SIZE: u32 = 64;

// Registers reserved in runtime for special purposes.
pub(crate) enum ReservedRegisters {
Expand Down Expand Up @@ -562,6 +562,7 @@ impl BrilligContext {
bit_size: u32,
) {
self.debug_show.const_instruction(result, constant);

self.push_opcode(BrilligOpcode::Const { destination: result, value: constant, bit_size });
}

Expand Down
2 changes: 1 addition & 1 deletion docs/scripts/codegen_nargo_reference.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ sidebar_position: 0
---
" > $NARGO_REFERENCE

cargo run -F codegen-docs -- info >> $NARGO_REFERENCE
cargo run --bin nargo -F codegen-docs -- info >> $NARGO_REFERENCE
42 changes: 21 additions & 21 deletions test_programs/execution_success/brillig_cow_regression/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ global MAX_NEW_CONTRACTS_PER_TX: u64 = 1;
global NUM_ENCRYPTED_LOGS_HASHES_PER_TX: u64 = 1;
global NUM_UNENCRYPTED_LOGS_HASHES_PER_TX: u64 = 1;
global NUM_FIELDS_PER_SHA256 = 2;
global CALLDATA_HASH_INPUT_SIZE = 169;
global CALL_DATA_HASH_LOG_FIELDS = 4;
global CALL_DATA_HASH_FULL_FIELDS = 165;
global TX_EFFECT_HASH_INPUT_SIZE = 169;
global TX_EFFECT_HASH_LOG_FIELDS = 4;
global TX_EFFECT_HASH_FULL_FIELDS = 165;

struct PublicDataUpdateRequest {
leaf_slot : Field,
Expand Down Expand Up @@ -99,7 +99,7 @@ impl U256 {
}

unconstrained fn main(kernel_data: DataToHash) -> pub [Field; NUM_FIELDS_PER_SHA256] {
let mut calldata_hash_inputs = [0; CALLDATA_HASH_INPUT_SIZE];
let mut tx_effects_hash_inputs = [0; TX_EFFECT_HASH_INPUT_SIZE];

let new_note_hashes = kernel_data.new_note_hashes;
let new_nullifiers = kernel_data.new_nullifiers;
Expand All @@ -111,65 +111,65 @@ unconstrained fn main(kernel_data: DataToHash) -> pub [Field; NUM_FIELDS_PER_SHA
let mut offset = 0;

for j in 0..MAX_NEW_NOTE_HASHES_PER_TX {
calldata_hash_inputs[offset + j] = new_note_hashes[j];
tx_effects_hash_inputs[offset + j] = new_note_hashes[j];
}
offset += MAX_NEW_NOTE_HASHES_PER_TX ;

for j in 0..MAX_NEW_NULLIFIERS_PER_TX {
calldata_hash_inputs[offset + j] = new_nullifiers[j];
tx_effects_hash_inputs[offset + j] = new_nullifiers[j];
}
offset += MAX_NEW_NULLIFIERS_PER_TX ;

for j in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX {
calldata_hash_inputs[offset + j * 2] =
tx_effects_hash_inputs[offset + j * 2] =
public_data_update_requests[j].leaf_slot;
calldata_hash_inputs[offset + j * 2 + 1] =
tx_effects_hash_inputs[offset + j * 2 + 1] =
public_data_update_requests[j].new_value;
}
offset += MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2;

for j in 0..MAX_NEW_L2_TO_L1_MSGS_PER_TX {
calldata_hash_inputs[offset + j] = newL2ToL1msgs[j];
tx_effects_hash_inputs[offset + j] = newL2ToL1msgs[j];
}
offset += MAX_NEW_L2_TO_L1_MSGS_PER_TX;

let contract_leaf = kernel_data.new_contracts[0];
calldata_hash_inputs[offset] = contract_leaf.hash();
tx_effects_hash_inputs[offset] = contract_leaf.hash();

offset += MAX_NEW_CONTRACTS_PER_TX;

let new_contracts = kernel_data.new_contracts;
calldata_hash_inputs[offset] = new_contracts[0].contract_address;
tx_effects_hash_inputs[offset] = new_contracts[0].contract_address;

calldata_hash_inputs[offset + 1] = new_contracts[0].portal_contract_address;
tx_effects_hash_inputs[offset + 1] = new_contracts[0].portal_contract_address;

offset += MAX_NEW_CONTRACTS_PER_TX * 2;

for j in 0..NUM_FIELDS_PER_SHA256 {
calldata_hash_inputs[offset + j] = encryptedLogsHash[j];
tx_effects_hash_inputs[offset + j] = encryptedLogsHash[j];
}

offset += NUM_ENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256;

for j in 0..NUM_FIELDS_PER_SHA256 {
calldata_hash_inputs[offset + j] = unencryptedLogsHash[j];
tx_effects_hash_inputs[offset + j] = unencryptedLogsHash[j];
}

offset += NUM_UNENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256;
assert_eq(offset, CALLDATA_HASH_INPUT_SIZE); // Sanity check
assert_eq(offset, TX_EFFECT_HASH_INPUT_SIZE); // Sanity check

let mut hash_input_flattened = [0; CALL_DATA_HASH_FULL_FIELDS * 32 + CALL_DATA_HASH_LOG_FIELDS * 16];
for offset in 0..CALL_DATA_HASH_FULL_FIELDS {
let input_as_bytes = calldata_hash_inputs[offset].to_be_bytes(32);
let mut hash_input_flattened = [0; TX_EFFECT_HASH_FULL_FIELDS * 32 + TX_EFFECT_HASH_LOG_FIELDS * 16];
for offset in 0..TX_EFFECT_HASH_FULL_FIELDS {
let input_as_bytes = tx_effects_hash_inputs[offset].to_be_bytes(32);
for byte_index in 0..32 {
hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index];
}
}

for log_field_index in 0..CALL_DATA_HASH_LOG_FIELDS {
let input_as_bytes = calldata_hash_inputs[CALL_DATA_HASH_FULL_FIELDS + log_field_index].to_be_bytes(16);
for log_field_index in 0..TX_EFFECT_HASH_LOG_FIELDS {
let input_as_bytes = tx_effects_hash_inputs[TX_EFFECT_HASH_FULL_FIELDS + log_field_index].to_be_bytes(16);
for byte_index in 0..16 {
hash_input_flattened[CALL_DATA_HASH_FULL_FIELDS * 32 + log_field_index * 16 + byte_index] = input_as_bytes[byte_index];
hash_input_flattened[TX_EFFECT_HASH_FULL_FIELDS * 32 + log_field_index * 16 + byte_index] = input_as_bytes[byte_index];
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
name = "should_fail_with_mismatch"
type = "bin"
authors = [""]
[dependencies]
38 changes: 38 additions & 0 deletions tooling/acvm_cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "acvm_cli"
description = "The entrypoint for executing the ACVM"
# x-release-please-start-version
version = "0.40.0"
# x-release-please-end
authors.workspace = true
edition.workspace = true
license.workspace = true
rust-version.workspace = true
repository.workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

# Rename binary from `acvm_cli` to `acvm`
[[bin]]
name = "acvm"
path = "src/main.rs"

[dependencies]
thiserror.workspace = true
toml.workspace = true
color-eyre = "0.6.2"
clap.workspace = true
acvm.workspace = true
nargo.workspace = true
const_format.workspace = true
bn254_blackbox_solver.workspace = true
acir.workspace = true

# Logs
tracing-subscriber.workspace = true
tracing-appender = "0.2.3"

[dev-dependencies]
rand = "0.8.5"
proptest = "1.2.0"
paste = "1.0.14"
79 changes: 79 additions & 0 deletions tooling/acvm_cli/src/cli/execute_cmd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use std::io::{self, Write};

use acir::circuit::Circuit;
use acir::native_types::WitnessMap;
use bn254_blackbox_solver::Bn254BlackBoxSolver;
use clap::Args;

use crate::cli::fs::inputs::{read_bytecode_from_file, read_inputs_from_file};
use crate::cli::fs::witness::save_witness_to_dir;
use crate::errors::CliError;
use nargo::ops::{execute_circuit, DefaultForeignCallExecutor};

use super::fs::witness::create_output_witness_string;

/// Executes a circuit to calculate its return value
#[derive(Debug, Clone, Args)]
pub(crate) struct ExecuteCommand {
/// Write the execution witness to named file
#[clap(long, short)]
output_witness: Option<String>,

/// The name of the toml file which contains the input witness map
#[clap(long, short)]
input_witness: String,

/// The name of the binary file containing circuit bytecode
#[clap(long, short)]
bytecode: String,

/// The working directory
#[clap(long, short)]
working_directory: String,

/// Set to print output witness to stdout
#[clap(long, short, action)]
print: bool,
}

fn run_command(args: ExecuteCommand) -> Result<String, CliError> {
let bytecode = read_bytecode_from_file(&args.working_directory, &args.bytecode)?;
let circuit_inputs = read_inputs_from_file(&args.working_directory, &args.input_witness)?;
let output_witness = execute_program_from_witness(&circuit_inputs, &bytecode, None)?;
let output_witness_string = create_output_witness_string(&output_witness)?;
if args.output_witness.is_some() {
save_witness_to_dir(
&output_witness_string,
&args.working_directory,
&args.output_witness.unwrap(),
)?;
}
Ok(output_witness_string)
}

pub(crate) fn run(args: ExecuteCommand) -> Result<String, CliError> {
let print = args.print;
let output_witness_string = run_command(args)?;
if print {
io::stdout().write_all(output_witness_string.as_bytes()).unwrap();
}
Ok(output_witness_string)
}

pub(crate) fn execute_program_from_witness(
inputs_map: &WitnessMap,
bytecode: &Vec<u8>,
foreign_call_resolver_url: Option<&str>,
) -> Result<WitnessMap, CliError> {
let blackbox_solver = Bn254BlackBoxSolver::new();
let circuit: Circuit = Circuit::deserialize_circuit(&bytecode)
.map_err(|_| CliError::CircuitDeserializationError())?;
let result = execute_circuit(
&circuit,
inputs_map.clone(),
&blackbox_solver,
&mut DefaultForeignCallExecutor::new(true, foreign_call_resolver_url),
)
.map_err(|e| CliError::CircuitExecutionError(e));
result
}
Loading

0 comments on commit 699f43d

Please sign in to comment.