Skip to content

Commit

Permalink
Merge pull request #44 from apoorvsadana/more_hints
Browse files Browse the repository at this point in the history
More hints
  • Loading branch information
drspacemn committed Oct 25, 2023
2 parents 0d6198f + b07ca5b commit c0d384e
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Rust artifacts
Cargo.lock
target/
.idea
.vscode

# Snos artifacts
build/*
Expand Down
10 changes: 3 additions & 7 deletions scripts/setup-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

CAIRO_VER="0.12.2"

if ! command -v cairo-compile > /dev/null
then
if ! command -v cairo-compile >/dev/null; then
echo "please start cairo($CAIRO_VER) dev environment"
exit 1
fi

if ! command -v starknet-compile-deprecated > /dev/null
then
if ! command -v starknet-compile-deprecated >/dev/null; then
echo "please start cairo($CAIRO_VER) dev environment"
exit 1
fi
Expand All @@ -19,7 +17,7 @@ git submodule update --init

FETCHED_CAIRO_VER="$(cat cairo-lang/src/starkware/cairo/lang/VERSION)"

if [ "$CAIRO_VER" != "$FETCHED_CAIRO_VER" ]; then
if [ "$CAIRO_VER" != "$FETCHED_CAIRO_VER" ]; then
echo "incorrect cairo ver($FETCHED_CAIRO_VAR) expecting $CAIROVER"
exit 1
fi
Expand All @@ -29,7 +27,6 @@ echo -e "setting up cairo dependencies...\n"
cp tests/dependencies/test_contract_interface.cairo cairo-lang/src/starkware/starknet/core/test_contract/
cp tests/dependencies/deprecated_syscalls.cairo cairo-lang/src/starkware/starknet/core/test_contract/


# setup token_for_testing path
mkdir -p cairo-lang/src/starkware/starknet/std_contracts/ERC20
cp tests/dependencies/ERC20.cairo cairo-lang/src/starkware/starknet/std_contracts/ERC20/
Expand All @@ -38,7 +35,6 @@ cp tests/dependencies/permitted.cairo cairo-lang/src/starkware/starknet/std_cont
mkdir -p cairo-lang/src/starkware/starknet/std_contracts/upgradability_proxy
cp tests/dependencies/initializable.cairo cairo-lang/src/starkware/starknet/std_contracts/upgradability_proxy


# compile cairo programs
echo -e "compmiling cairo programs...\n"
mkdir -p build/programs
Expand Down
11 changes: 11 additions & 0 deletions src/hints/hints_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,14 @@ pub const LOAD_NEXT_TX: &str = "tx = next(transactions)\ntx_type_bytes = \
pub const LOAD_CONTRACT_ADDRESS: &str = "from starkware.starknet.business_logic.transaction.objects import \
InternalL1Handler\nids.contract_address = (\ntx.contract_address if \
isinstance(tx, InternalL1Handler) else tx.sender_address\n)";

pub const PREPARE_CONSTRUCTOR_EXECUTION: &str = "ids.contract_address_salt = tx.contract_address_salt\nids.class_hash \
= tx.class_hash\nids.constructor_calldata_size = \
len(tx.constructor_calldata)\nids.constructor_calldata = \
segments.gen_arg(arg=tx.constructor_calldata)";

pub const TRANSACTION_VERSION: &str = "memory[ap] = to_felt_or_relocatable(tx.version)";

pub const ASSERT_TRANSACTION_HASH: &str =
"assert ids.transaction_hash == tx.hash_value, (\n \"Computed transaction_hash is inconsistent with the hash \
in the transaction. \"\n f\"Computed hash = {ids.transaction_hash}, Expected hash = {tx.hash_value}.\")";
106 changes: 103 additions & 3 deletions src/hints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub mod hints_raw;
use std::any::Any;
use std::collections::HashMap;
use std::rc::Rc;
use std::slice::Iter;
use std::vec::IntoIter;

use cairo_vm::felt::Felt252;
use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::{
Expand All @@ -20,6 +20,9 @@ use cairo_vm::vm::errors::hint_errors::HintError;
use cairo_vm::vm::vm_core::VirtualMachine;

use crate::config::DEFAULT_INPUT_PATH;
use crate::hints::hints_raw::{
ASSERT_TRANSACTION_HASH, LOAD_NEXT_TX, PREPARE_CONSTRUCTOR_EXECUTION, TRANSACTION_VERSION,
};
use crate::io::{InternalTransaction, StarknetOsInput};

pub fn sn_hint_processor() -> BuiltinHintProcessor {
Expand Down Expand Up @@ -71,6 +74,21 @@ pub fn sn_hint_processor() -> BuiltinHintProcessor {
let transactions_len_hint = HintFunc(Box::new(transactions_len));
hint_processor.add_hint(String::from(hints_raw::TRANSACTIONS_LEN), Rc::new(transactions_len_hint));

let enter_syscall_scopes_hint = HintFunc(Box::new(enter_syscall_scopes));
hint_processor.add_hint(String::from(hints_raw::ENTER_SYSCALL_SCOPES), Rc::new(enter_syscall_scopes_hint));

let load_next_tx_hint = HintFunc(Box::new(load_next_tx));
hint_processor.add_hint(String::from(LOAD_NEXT_TX), Rc::new(load_next_tx_hint));

let prepare_constructor_execution_hint = HintFunc(Box::new(prepare_constructor_execution));
hint_processor.add_hint(String::from(PREPARE_CONSTRUCTOR_EXECUTION), Rc::new(prepare_constructor_execution_hint));

let transaction_version_hint = HintFunc(Box::new(transaction_version));
hint_processor.add_hint(String::from(TRANSACTION_VERSION), Rc::new(transaction_version_hint));

let assert_transaction_hash_hint = HintFunc(Box::new(assert_transaction_hash));
hint_processor.add_hint(String::from(ASSERT_TRANSACTION_HASH), Rc::new(assert_transaction_hash_hint));

hint_processor
}

Expand Down Expand Up @@ -242,7 +260,7 @@ pub fn enter_syscall_scopes(
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let os_input = exec_scopes.get::<StarknetOsInput>("os_input").unwrap();
let transactions: Box<dyn Any> = Box::new([os_input.transactions.into_iter()].into_iter());
let transactions: Box<dyn Any> = Box::new(os_input.transactions.into_iter());
exec_scopes.enter_scope(HashMap::from_iter([(String::from("transactions"), transactions)]));
Ok(())
}
Expand All @@ -259,9 +277,91 @@ pub fn load_next_tx(
ap_tracking: &ApTracking,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let mut transactions = exec_scopes.get::<Iter<InternalTransaction>>("transactions")?;
let mut transactions = exec_scopes.get::<IntoIter<InternalTransaction>>("transactions")?;
// Safe to unwrap because the remaining number of txs is checked in the cairo code.
let tx = transactions.next().unwrap();
exec_scopes.insert_value("transactions", transactions);
exec_scopes.insert_value("tx", tx.clone());
insert_value_from_var_name("tx_type", Felt252::from_bytes_be(tx.r#type.as_bytes()), vm, ids_data, ap_tracking)
}

/// Implements hint:
///
/// ids.contract_address_salt = tx.contract_address_salt
/// ids.class_hash = tx.class_hash
/// ids.constructor_calldata_size = len(tx.constructor_calldata)
/// ids.constructor_calldata = segments.gen_arg(arg=tx.constructor_calldata)
pub fn prepare_constructor_execution(
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let tx = exec_scopes.get::<InternalTransaction>("tx")?;
insert_value_from_var_name(
"contract_address_salt",
tx.contract_address_salt.expect("`contract_address_salt` must be present"),
vm,
ids_data,
ap_tracking,
)?;
insert_value_from_var_name(
"class_hash",
// using `contract_hash` instead of `class_hash` as the that's how the
// input.json is structured
tx.contract_hash.expect("`contract_hash` must be present"),
vm,
ids_data,
ap_tracking,
)?;

let constructor_calldata_size = match &tx.constructor_calldata {
None => 0,
Some(calldata) => calldata.len(),
};
insert_value_from_var_name("constructor_calldata_size", constructor_calldata_size, vm, ids_data, ap_tracking)?;

let constructor_calldata = tx.constructor_calldata.unwrap_or_default().iter().map(|felt| felt.into()).collect();
let constructor_calldata_base = vm.add_memory_segment();
vm.load_data(constructor_calldata_base, &constructor_calldata)?;
insert_value_from_var_name("constructor_calldata", constructor_calldata_base, vm, ids_data, ap_tracking)
}

/// Implements hint:
///
/// memory[ap] = to_felt_or_relocatable(tx.version)
pub fn transaction_version(
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
_ids_data: &HashMap<String, HintReference>,
_ap_tracking: &ApTracking,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let tx = exec_scopes.get::<InternalTransaction>("tx")?;
insert_value_into_ap(vm, tx.version.expect("Transaction version should be set"))
}

/// Implements hint:
///
/// assert ids.transaction_hash == tx.hash_value, (
/// "Computed transaction_hash is inconsistent with the hash in the transaction. "
/// f"Computed hash = {ids.transaction_hash}, Expected hash = {tx.hash_value}.")
pub fn assert_transaction_hash(
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let tx = exec_scopes.get::<InternalTransaction>("tx")?;
let transaction_hash = get_integer_from_var_name("transaction_hash", vm, ids_data, ap_tracking)?.into_owned();

assert_eq!(
tx.hash_value, transaction_hash,
"Computed transaction_hash is inconsistent with the hash in the transaction. Computed hash = {}, Expected \
hash = {}.",
transaction_hash, tx.hash_value
);
Ok(())
}

0 comments on commit c0d384e

Please sign in to comment.