Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(avm-simulator): update e2e test #5283

Merged
merged 1 commit into from
Mar 18, 2024
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
8 changes: 8 additions & 0 deletions avm-transpiler/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ fn main() {
warn!("Contract already transpiled. Skipping.");
return;
}

// Backup the original file
std::fs::copy(
Path::new(in_contract_artifact_path),
Path::new(&(in_contract_artifact_path.clone() + ".bak")),
)
.expect("Unable to backup file");

// Parse json into contract object
let contract: CompiledAcirContract =
serde_json::from_str(&contract_json).expect("Unable to parse json");
Expand Down
3 changes: 0 additions & 3 deletions avm-transpiler/src/transpile_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,11 @@ impl From<CompiledAcirContract> for TranspiledContract {
fn from(contract: CompiledAcirContract) -> Self {
let mut functions = Vec::new();

// Note, in aztec_macros/lib.rs, avm_ prefix is pushed to function names with the #[aztec(public-vm)] tag
let re = Regex::new(r"avm_.*$").unwrap();
for function in contract.functions {
// TODO(4269): once functions are tagged for transpilation to AVM, check tag
if function
.custom_attributes
.contains(&"aztec(public-vm)".to_string())
&& re.is_match(function.name.as_str())
{
info!(
"Transpiling AVM function {} on contract {}",
Expand Down
1 change: 1 addition & 0 deletions noir-projects/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ FROM aztecprotocol/noir as noir
FROM aztecprotocol/avm-transpiler as transpiler

FROM ubuntu:lunar AS builder
RUN apt-get update && apt-get install -y parallel
# Copy in nargo
COPY --from=noir /usr/src/noir/noir-repo/target/release/nargo /usr/src/noir/noir-repo/target/release/nargo
ENV PATH="/usr/src/noir/noir-repo/target/release:${PATH}"
Expand Down
1 change: 1 addition & 0 deletions noir-projects/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ WORKDIR /build
COPY --dir aztec-nr noir-contracts noir-protocol-circuits .

build:
RUN apt-get update && apt-get install -y parallel
RUN cd noir-contracts && NARGO=nargo TRANSPILER=avm-transpiler ./bootstrap.sh
RUN cd noir-protocol-circuits && NARGO=nargo ./bootstrap.sh
SAVE ARTIFACT aztec-nr
Expand Down
9 changes: 3 additions & 6 deletions noir-projects/noir-contracts/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ echo "Compiling contracts..."
NARGO=${NARGO:-../../noir/noir-repo/target/release/nargo}
$NARGO compile --silence-warnings

echo "Transpiling avm contracts..."
for contract_json in target/avm_test_*.json; do
echo Transpiling $contract_json...
TRANSPILER=${TRANSPILER:-../../avm-transpiler/target/release/avm-transpiler}
$TRANSPILER $contract_json $contract_json
done
echo "Transpiling avm contracts... (only '#[aztec(public-vm)]')"
TRANSPILER=${TRANSPILER:-../../avm-transpiler/target/release/avm-transpiler}
ls target/avm_*.json | parallel -L8 "$TRANSPILER {} {}"
122 changes: 71 additions & 51 deletions noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ impl Deserialize<2> for Note {

contract AvmTest {
use crate::Note;

global big_field_128_bits: Field = 0x001234567890abcdef1234567890abcdef;
global big_field_136_bits: Field = 0x991234567890abcdef1234567890abcdef;

Expand All @@ -28,7 +28,7 @@ contract AvmTest {
use dep::aztec::state_vars::PublicMutable;
use dep::aztec::protocol_types::{address::{AztecAddress, EthAddress}, constants::L1_TO_L2_MESSAGE_LENGTH};
use dep::aztec::protocol_types::abis::function_selector::FunctionSelector;
use dep::aztec::protocol_types::{hash::pedersen_hash, traits::{ToField}};
use dep::aztec::protocol_types::traits::{ToField};
use dep::compressed_string::CompressedString;

// avm lib
Expand All @@ -40,91 +40,109 @@ contract AvmTest {
map: Map<AztecAddress, PublicMutable<u32>>,
}

/************************************************************************
* Storage
************************************************************************/
unconstrained fn view_storage_single() -> pub Field {
storage.single.read()
}

unconstrained fn view_storage_list() -> pub [Field; 2] {
storage.list.read().serialize()
}

unconstrained fn view_storage_map(address: AztecAddress) -> pub u32 {
storage.map.at(address).read()
}

#[aztec(public-vm)]
fn setStorageSingle(a: Field) {
fn set_storage_single(a: Field) {
storage.single.write(a);
}

#[aztec(public-vm)]
fn readStorageSingle() -> pub Field {
fn read_storage_single() -> pub Field {
storage.single.read()
}

#[aztec(public-vm)]
fn setReadStorageSingle(a: Field) -> pub Field {
fn set_read_storage_single(a: Field) -> pub Field {
storage.single.write(a);
storage.single.read()
}

#[aztec(public-vm)]
fn setStorageList(a: Field, b: Field) {
fn set_storage_list(a: Field, b: Field) {
storage.list.write(Note { a, b });
}

#[aztec(public-vm)]
fn readStorageList() -> pub [Field; 2] {
fn read_storage_list() -> pub [Field; 2] {
let note: Note = storage.list.read();
note.serialize()
}

#[aztec(public-vm)]
fn setStorageMap(to: AztecAddress, amount: u32) -> pub Field {
fn set_storage_map(to: AztecAddress, amount: u32) -> pub Field {
storage.map.at(to).write(amount);
// returns storage slot for key
pedersen_hash([storage.map.storage_slot, to.to_field()], 0)
dep::std::hash::pedersen_hash([storage.map.storage_slot, to.to_field()])
}

#[aztec(public-vm)]
fn addStorageMap(to: AztecAddress, amount: u32) -> pub Field {
fn add_storage_map(to: AztecAddress, amount: u32) -> pub Field {
let new_balance = storage.map.at(to).read().add(amount);
storage.map.at(to).write(new_balance);
// returns storage slot for key
pedersen_hash([storage.map.storage_slot, to.to_field()], 0)
dep::std::hash::pedersen_hash([storage.map.storage_slot, to.to_field()])
}

#[aztec(public-vm)]
fn readStorageMap(address: AztecAddress) -> pub u32 {
fn read_storage_map(address: AztecAddress) -> pub u32 {
storage.map.at(address).read()
}

#[aztec(public-vm)]
fn addArgsReturn(argA: Field, argB: Field) -> pub Field {
argA + argB
fn add_args_return(arg_a: Field, arg_b: Field) -> pub Field {
arg_a + arg_b
}

/************************************************************************
* General Opcodes
************************************************************************/
#[aztec(public-vm)]
fn setOpcodeUint8() -> pub u8 {
fn set_opcode_u8() -> pub u8 {
8 as u8
}

#[aztec(public-vm)]
fn setOpcodeUint32() -> pub u32 {
fn set_opcode_u32() -> pub u32 {
1 << 30 as u32
}

#[aztec(public-vm)]
fn setOpcodeUint64() -> pub u64 {
fn set_opcode_u64() -> pub u64 {
1 << 60 as u64
}

#[aztec(public-vm)]
fn setOpcodeSmallField() -> pub Field {
fn set_opcode_small_field() -> pub Field {
big_field_128_bits
}

#[aztec(public-vm)]
fn setOpcodeBigField() -> pub Field {
fn set_opcode_big_field() -> pub Field {
big_field_136_bits
}

#[aztec(public-vm)]
fn addU128(a: U128, b: U128) -> pub U128 {
fn add_u128(a: U128, b: U128) -> pub U128 {
a + b
}

// /************************************************************************
// * Hashing functions
// ************************************************************************/
/************************************************************************
* Hashing functions
************************************************************************/
#[aztec(public-vm)]
fn keccak_hash(data: [Field; 3]) -> pub [Field; 2] {
keccak256(data)
Expand All @@ -145,71 +163,71 @@ contract AvmTest {
dep::std::hash::pedersen_hash(data)
}

// /************************************************************************
// * AvmContext functions
// ************************************************************************/
/************************************************************************
* AvmContext functions
************************************************************************/
#[aztec(public-vm)]
fn getAddress() -> pub AztecAddress {
fn get_address() -> pub AztecAddress {
context.address()
}

#[aztec(public-vm)]
fn getStorageAddress() -> pub AztecAddress {
fn get_storage_address() -> pub AztecAddress {
context.storage_address()
}

#[aztec(public-vm)]
fn getSender() -> pub AztecAddress {
fn get_sender() -> pub AztecAddress {
context.sender()
}

#[aztec(public-vm)]
fn getOrigin() -> pub AztecAddress {
fn get_origin() -> pub AztecAddress {
context.origin()
}

#[aztec(public-vm)]
fn getPortal() -> pub EthAddress {
fn get_portal() -> pub EthAddress {
context.portal()
}

#[aztec(public-vm)]
fn getFeePerL1Gas() -> pub Field {
fn get_fee_per_l1_gas() -> pub Field {
context.fee_per_l1_gas()
}

#[aztec(public-vm)]
fn getFeePerL2Gas() -> pub Field {
fn get_fee_per_l2_gas() -> pub Field {
context.fee_per_l2_gas()
}

#[aztec(public-vm)]
fn getFeePerDaGas() -> pub Field {
fn get_fee_per_da_gas() -> pub Field {
context.fee_per_da_gas()
}

#[aztec(public-vm)]
fn getChainId() -> pub Field {
fn get_chain_id() -> pub Field {
context.chain_id()
}

#[aztec(public-vm)]
fn getVersion() -> pub Field {
fn get_version() -> pub Field {
context.version()
}

#[aztec(public-vm)]
fn getBlockNumber() -> pub Field {
fn get_block_number() -> pub Field {
context.block_number()
}

#[aztec(public-vm)]
fn getTimestamp() -> pub Field {
fn get_timestamp() -> pub Field {
context.timestamp()
}

// #[aztec(public-vm)]
// fn getContractCallDepth() -> pub Field {
// fn get_contract_call_depth() -> pub Field {
// context.contract_call_depth()
// }

Expand Down Expand Up @@ -273,7 +291,7 @@ contract AvmTest {
// Directly call the external call opcode to initiate a nested call to the add function
#[aztec(public-vm)]
fn raw_nested_call_to_add(argA: Field, argB: Field) -> pub Field {
let selector = FunctionSelector::from_signature("avm_addArgsReturn(Field,Field)").to_field();
let selector = FunctionSelector::from_signature("add_args_return(Field,Field)").to_field();
let gas = [/*l1Gas*/42, /*l2Gas*/24, /*daGas*/420];

// Nested call
Expand All @@ -292,7 +310,7 @@ contract AvmTest {
// Use the `call_public_function` wrapper to initiate a nested call to the add function
#[aztec(public-vm)]
fn nested_call_to_add(argA: Field, argB: Field) -> pub Field {
let selector = FunctionSelector::from_signature("avm_addArgsReturn(Field,Field)");
let selector = FunctionSelector::from_signature("add_args_return(Field,Field)");

// Nested call using standard context interface function
let returnData: [Field; 1] = context.call_public_function(context.address(), selector, [argA, argB]);
Expand All @@ -306,40 +324,42 @@ contract AvmTest {
// Directly call_static the external call opcode to initiate a nested call to the add function
#[aztec(public-vm)]
fn raw_nested_static_call_to_add(argA: Field, argB: Field) -> pub (Field, u8) {
let selector = FunctionSelector::from_signature("avm_addArgsReturn(Field,Field)").to_field();
let selector = FunctionSelector::from_signature("add_args_return(Field,Field)").to_field();
let gas = [/*l1Gas*/42, /*l2Gas*/24, /*daGas*/420];

let (resultData, success): ([Field; 1], u8) = context.call_static(gas, context.address(), [argA, argB], selector);

(resultData[0], success)
}

// Directly call_static setAdmin. Should fail since it's accessing storage.
// Directly call_static `set_storage_single`. Should fail since it's accessing storage.
#[aztec(public-vm)]
fn raw_nested_static_call_to_set_admin() -> pub u8 {
let selector = FunctionSelector::from_signature("avm_setAdmin()").to_field();
fn raw_nested_static_call_to_set_storage() -> pub u8 {
let selector = FunctionSelector::from_signature("set_storage_single(Field)").to_field();
let gas = [/*l1Gas*/42, /*l2Gas*/24, /*daGas*/420];
let calldata: [Field; 1] = [20];

let (_returnData, success): ([Field; 0], u8) = context.call_static(gas, context.address(), [], selector);
let (_returnData, success): ([Field; 0], u8) = context.call_static(gas, context.address(), calldata, selector);

success
}

// Indirectly call_static the external call opcode to initiate a nested call to the add function
#[aztec(public-vm)]
fn nested_static_call_to_add(argA: Field, argB: Field) -> pub Field {
let selector = FunctionSelector::from_signature("avm_addArgsReturn(Field,Field)");
let selector = FunctionSelector::from_signature("add_args_return(Field,Field)");

let resultData: [Field; 1] = context.static_call_public_function(context.address(), selector, [argA, argB]);

resultData[0]
}

// Indirectly call_static setAdmin. Should revert since it's accessing storage.
// Indirectly call_static `set_storage_single`. Should revert since it's accessing storage.
#[aztec(public-vm)]
fn nested_static_call_to_set_admin() {
let selector = FunctionSelector::from_signature("avm_setAdmin()");
fn nested_static_call_to_set_storage() {
let selector = FunctionSelector::from_signature("set_storage_single(Field)");
let calldata: [Field; 1] = [20];

let _resultData: [Field; 0] = context.static_call_public_function(context.address(), selector, []);
let _resultData: [Field; 0] = context.static_call_public_function(context.address(), selector, calldata);
}
}
3 changes: 0 additions & 3 deletions noir/noir-repo/aztec_macros/src/transforms/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@ pub fn transform_vm_function(
// We want the function to be seen as a public function
func.def.is_unconstrained = true;

// NOTE: the line below is a temporary hack to trigger external transpilation tools
// It will be removed once the transpiler is integrated into the Noir compiler
func.def.name.0.contents = format!("avm_{}", func.def.name.0.contents);
Ok(())
}

Expand Down
Loading
Loading