Skip to content

Commit

Permalink
Partial implementation of the BusinessLogicSyscallHandler._deploy met…
Browse files Browse the repository at this point in the history
…hod (#17)

* Add SyscallRequest::Deploy(DeployRequestStruct)

* Start BusinessLogicSyscallHandler::_deploy implementation

* Add naive implementation of fn Os::ContractAddress::calculate_contract_address_from_hash

* add starknet-crypto dependecie

* first implementation of fn compute_hash_on_elements + unit tests

* use get_integer_range

* Add bigint! and bigint_str! macros

* Update fns calculate_contract_address_from_hash && compute_hash_on_elements

* add SyscallHandlerError::FailToComputeHash

* Minor midifications

* mv src/core/os/contact_address.rs -> src/hash_utils.rs

* handle Errors && cargo clippy

* delete syscall_handler.rs

* fix merge main conflicts

* add deploy read_syscall_request

* Add PartialEq to SyscallRequest

* Add read_deploy_syscall_request

* Modify BusinessLogicSyscallHandler::new to return self + BusinessLogicSyscallHandler::Default

* Add test_calculate_contract_address_from_hash

* Modify DeployStruct.deploy_from_zero to be a usize + unit test

Co-authored-by: Pedro Fontana <pedro.fontana@lamdaclass.com>
  • Loading branch information
pefontana and Pedro Fontana committed Dec 21, 2022
1 parent f398458 commit f6eeeef
Show file tree
Hide file tree
Showing 10 changed files with 330 additions and 17 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ serde_json = { version = "1.0", features = ["arbitrary_precision"] }
thiserror = { version = "1.0.32" }
num-traits = "0.2.15"
num-integer = "0.1.45"
starknet-crypto = "0.2.0"
8 changes: 8 additions & 0 deletions src/core/errors/syscall_handler_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ pub enum SyscallHandlerError {
SegmentationFault,
#[error("Couldn't convert BigInt to usize")]
BigintToUsizeFail,
#[error("Couldn't compure hash")]
FailToComputeHash,
#[error("Expected DesployRequestStruct")]
ExpectedDeployRequestStruct,
#[error("Expected EmitEventStruct")]
ExpectedEmitEventStruct,
#[error("The deploy_from_zero field in the deploy system call must be 0 or 1, found: {0}")]
DeployFromZero(usize),
#[error("Hint not implemented")]
NotImplemented,
#[error("HintData is incorrect")]
Expand Down
86 changes: 82 additions & 4 deletions src/core/syscalls/business_logic_syscall_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ use super::syscall_request::*;
use crate::business_logic::execution::objects::*;
use crate::core::errors::syscall_handler_errors::SyscallHandlerError;
use crate::core::syscalls::syscall_handler::SyscallHandler;
use crate::hash_utils::calculate_contract_address_from_hash;
use crate::utils::*;
use cairo_rs::types::relocatable::{MaybeRelocatable, Relocatable};
use cairo_rs::vm::vm_core::VirtualMachine;
use num_bigint::BigInt;
use num_traits::{One, Zero};

//* -----------------------------------
//* BusinessLogicHandler implementation
Expand All @@ -17,16 +19,24 @@ use num_bigint::BigInt;
pub struct BusinessLogicSyscallHandler {
tx_execution_context: Rc<RefCell<TransactionExecutionContext>>,
events: Rc<RefCell<Vec<OrderedEvent>>>,
contract_address: u64,
}

impl BusinessLogicSyscallHandler {
pub fn new() -> Result<Self, SyscallHandlerError> {
pub fn new() -> Self {
let events = Rc::new(RefCell::new(Vec::new()));
let tx_execution_context = Rc::new(RefCell::new(TransactionExecutionContext::new()));
Ok(BusinessLogicSyscallHandler {
BusinessLogicSyscallHandler {
events,
tx_execution_context,
})
contract_address: 0,
}
}
}

impl Default for BusinessLogicSyscallHandler {
fn default() -> Self {
Self::new()
}
}

Expand Down Expand Up @@ -73,7 +83,50 @@ impl SyscallHandler for BusinessLogicSyscallHandler {
fn _get_tx_info_ptr(&self, _vm: VirtualMachine) {
todo!()
}
fn _deploy(&self, _vm: VirtualMachine, _syscall_ptr: Relocatable) -> i32 {

fn _deploy(
&self,
vm: &VirtualMachine,
syscall_ptr: Relocatable,
) -> Result<i32, SyscallHandlerError> {
let request = if let SyscallRequest::Deploy(request) =
self._read_and_validate_syscall_request("deploy", vm, syscall_ptr)?
{
request
} else {
return Err(SyscallHandlerError::ExpectedDeployRequestStruct);
};

if !(request.deploy_from_zero.is_zero() || request.deploy_from_zero.is_one()) {
return Err(SyscallHandlerError::DeployFromZero(
request.deploy_from_zero,
));
};

let constructor_calldata = get_integer_range(
vm,
&request.constructor_calldata,
bigint_to_usize(&request.constructor_calldata_size)?,
)?;

let class_hash = &request.class_hash;

let deployer_address = if request.deploy_from_zero.is_zero() {
self.contract_address
} else {
0
};

let _contract_address = calculate_contract_address_from_hash(
&request.contract_address_salt,
class_hash,
&constructor_calldata,
deployer_address,
)?;

// Initialize the contract.
let (_sign, _class_hash_bytes) = request.class_hash.to_bytes_be();

todo!()
}

Expand Down Expand Up @@ -132,14 +185,18 @@ impl SyscallHandler for BusinessLogicSyscallHandler {

#[cfg(test)]
mod tests {
use crate::bigint;
use crate::business_logic::execution::objects::OrderedEvent;
use crate::core::errors::syscall_handler_errors::SyscallHandlerError;
use crate::core::syscalls::business_logic_syscall_handler::BusinessLogicSyscallHandler;
use crate::core::syscalls::hint_code::{DEPLOY_SYSCALL_CODE, EMIT_EVENT_CODE};
use crate::core::syscalls::syscall_handler::*;
use crate::utils::test_utils::*;
use cairo_rs::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::{
BuiltinHintProcessor, HintProcessorData,
};
use cairo_rs::hint_processor::hint_processor_definition::HintProcessor;
use cairo_rs::relocatable;
use cairo_rs::types::exec_scope::ExecutionScopes;
use cairo_rs::types::relocatable::{MaybeRelocatable, Relocatable};
use cairo_rs::vm::errors::memory_errors::MemoryError;
Expand Down Expand Up @@ -270,4 +327,25 @@ mod tests {
1
);
}

#[test]
fn deploy_from_zero_error() {
let syscall = BusinessLogicSyscallHandler::new();
let mut vm = vm!();

add_segments!(vm, 2);

vm.insert_value(&relocatable!(1, 0), bigint!(0)).unwrap();
vm.insert_value(&relocatable!(1, 1), bigint!(1)).unwrap();
vm.insert_value(&relocatable!(1, 2), bigint!(2)).unwrap();
vm.insert_value(&relocatable!(1, 3), bigint!(3)).unwrap();
vm.insert_value(&relocatable!(1, 4), relocatable!(1, 20))
.unwrap();
vm.insert_value(&relocatable!(1, 5), bigint!(4)).unwrap();

assert_eq!(
syscall._deploy(&vm, relocatable!(1, 0)),
Err(SyscallHandlerError::DeployFromZero(4))
)
}
}
46 changes: 44 additions & 2 deletions src/core/syscalls/syscall_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ pub(crate) trait SyscallHandler {

fn send_message_to_l1(&self, vm: VirtualMachine, syscall_ptr: Relocatable);
fn _get_tx_info_ptr(&self, vm: VirtualMachine);
fn _deploy(&self, vm: VirtualMachine, syscall_ptr: Relocatable) -> i32;
fn _deploy(
&self,
vm: &VirtualMachine,
syscall_ptr: Relocatable,
) -> Result<i32, SyscallHandlerError>;

fn _read_and_validate_syscall_request(
&self,
Expand Down Expand Up @@ -81,6 +85,7 @@ pub(crate) trait SyscallHandler {
) -> Result<SyscallRequest, SyscallHandlerError> {
match syscall_name {
"emit_event" => EmitEventStruct::from_ptr(vm, syscall_ptr),
"deploy" => DeployRequestStruct::from_ptr(vm, syscall_ptr),
"library_call" => LibraryCallStruct::from_ptr(vm, syscall_ptr),
_ => Err(SyscallHandlerError::UnknownSyscall),
}
Expand All @@ -103,7 +108,7 @@ impl SyscallHintProcessor<BusinessLogicSyscallHandler> {
) -> Result<SyscallHintProcessor<BusinessLogicSyscallHandler>, SyscallHandlerError> {
Ok(SyscallHintProcessor {
builtin_hint_processor: BuiltinHintProcessor::new_empty(),
syscall_handler: BusinessLogicSyscallHandler::new()?,
syscall_handler: BusinessLogicSyscallHandler::new(),
})
}
}
Expand Down Expand Up @@ -215,3 +220,40 @@ fn get_syscall_ptr(
.into_owned();
Ok(syscall_ptr)
}

#[cfg(test)]
mod tests {

use crate::{add_segments, bigint, utils::test_utils::vm};
use cairo_rs::relocatable;
use num_bigint::{BigInt, Sign};

use super::*;

#[test]
fn read_deploy_syscall_request() {
let syscall = BusinessLogicSyscallHandler::new();
let mut vm = vm!();
add_segments!(vm, 2);

vm.insert_value(&relocatable!(1, 0), bigint!(0)).unwrap();
vm.insert_value(&relocatable!(1, 1), bigint!(1)).unwrap();
vm.insert_value(&relocatable!(1, 2), bigint!(2)).unwrap();
vm.insert_value(&relocatable!(1, 3), bigint!(3)).unwrap();
vm.insert_value(&relocatable!(1, 4), relocatable!(1, 20))
.unwrap();
vm.insert_value(&relocatable!(1, 5), bigint!(4)).unwrap();

assert_eq!(
syscall.read_syscall_request("deploy", &vm, relocatable!(1, 0)),
Ok(SyscallRequest::Deploy(DeployRequestStruct {
_selector: bigint!(0),
class_hash: bigint!(1),
contract_address_salt: bigint!(2),
constructor_calldata_size: bigint!(3),
constructor_calldata: relocatable!(1, 20),
deploy_from_zero: 4,
}))
)
}
}
1 change: 0 additions & 1 deletion src/core/syscalls/syscall_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ mod tests {

use super::SyscallInfo;
use super::*;
use crate::utils::test_utils::*;
use num_bigint::BigInt;
use std::str::FromStr;

Expand Down
49 changes: 47 additions & 2 deletions src/core/syscalls/syscall_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ use cairo_rs::types::relocatable::Relocatable;
use cairo_rs::vm::vm_core::VirtualMachine;
use num_bigint::BigInt;

#[derive(Debug, PartialEq)]
pub(crate) enum SyscallRequest {
EmitEvent(EmitEventStruct),
Deploy(DeployRequestStruct),
LibraryCall(LibraryCallStruct),
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct EmitEventStruct {
#[allow(unused)] // TODO: Remove once used.
pub(crate) selector: BigInt,
Expand All @@ -19,8 +21,23 @@ pub(crate) struct EmitEventStruct {
pub(crate) data: Relocatable,
}

#[derive(Clone, Debug, PartialEq)]
pub(crate) struct DeployRequestStruct {
// The system call selector (= DEPLOY_SELECTOR).
pub(crate) _selector: BigInt,
// The hash of the class to deploy.
pub(crate) class_hash: BigInt,
// A salt for the new contract address calculation.
pub(crate) contract_address_salt: BigInt,
// The size of the calldata for the constructor.
pub(crate) constructor_calldata_size: BigInt,
// The calldata for the constructor.
pub(crate) constructor_calldata: Relocatable,
// Used for deterministic contract address deployment.
pub(crate) deploy_from_zero: usize,
}
#[allow(unused)] // TODO: Remove once used.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct LibraryCallStruct {
pub(crate) selector: BigInt,
pub(crate) class_hash: usize,
Expand All @@ -42,6 +59,11 @@ impl From<EmitEventStruct> for SyscallRequest {
}
}

impl From<DeployRequestStruct> for SyscallRequest {
fn from(deploy_request_struct: DeployRequestStruct) -> SyscallRequest {
SyscallRequest::Deploy(deploy_request_struct)
}
}
impl From<LibraryCallStruct> for SyscallRequest {
fn from(library_call_struct: LibraryCallStruct) -> SyscallRequest {
SyscallRequest::LibraryCall(library_call_struct)
Expand Down Expand Up @@ -90,3 +112,26 @@ impl FromPtr for LibraryCallStruct {
.into())
}
}

impl FromPtr for DeployRequestStruct {
fn from_ptr(
vm: &VirtualMachine,
syscall_ptr: Relocatable,
) -> Result<SyscallRequest, SyscallHandlerError> {
let _selector = get_big_int(vm, &syscall_ptr)?;
let class_hash = get_big_int(vm, &(&syscall_ptr + 1))?;
let contract_address_salt = get_big_int(vm, &(&syscall_ptr + 2))?;
let constructor_calldata_size = get_big_int(vm, &(&syscall_ptr + 3))?;
let constructor_calldata = get_relocatable(vm, &(&syscall_ptr + 4))?;
let deploy_from_zero = get_integer(vm, &(&syscall_ptr + 5))?;

Ok(SyscallRequest::Deploy(DeployRequestStruct {
_selector,
class_hash,
contract_address_salt,
constructor_calldata_size,
constructor_calldata,
deploy_from_zero,
}))
}
}
Loading

0 comments on commit f6eeeef

Please sign in to comment.