diff --git a/README.md b/README.md index ef8aed7..c7ca653 100644 --- a/README.md +++ b/README.md @@ -16,50 +16,32 @@ To set up the project environment and run the bootloader, follow these steps: 4. **Running the Bootloader**: Start the bootloader with `python run.py`, which will load and execute the compiled Cairo1 contract within the Cairo0 environment. +5. **Preparing bootloader_input.json (Optional)**: + - Run `Scarb build` in the contract folder. + - Use `starknet-sierra-compile INPUT OUTPUT --add-pythonic-hints`. + - Add a return footer at the end of the contract's bytecode (increase the bytecode segment size by one). + - Supply `bootloader_input.json` with new contract sierra class json. + --- This example showcases merge of Cairo0 host provable environment and a Cairo1 developer frendly language: ```cairo -#[starknet::interface] -pub trait IHelloBootloader { - fn main(ref self: TContractState, input: Array) -> Array; -} - #[starknet::contract] -mod HelloBootloader { - #[derive(Drop, Serde)] - struct Input { - a: u32, - b: u32, - c: u32, - } - - #[derive(Drop, Serde)] - struct Output { - a_2: u32, - b_2: u32, - c_2: u32, - } +mod Factorial { + use starknet::{ContractAddress, SyscallResult, SyscallResultTraitImpl}; + use starknet::syscalls::call_contract_syscall; #[storage] - struct Storage {} - - #[abi(embed_v0)] - impl HelloBootloaderImpl of super::IHelloBootloader { - fn main(ref self: ContractState, input: Array) -> Array { - let mut input_span = input.span(); - let input = Serde::::deserialize(ref input_span).unwrap(); - - let a_2 = input.a * input.a; - let b_2 = input.b * input.b; - let c_2 = input.c * input.c; - assert(a_2 + b_2 == c_2, 'invalid value'); - - let mut output = array![]; - Output { a_2, b_2, c_2, }.serialize(ref output); - output - } + struct Storage{} + + #[external(v0)] + fn main(ref self: ContractState, address: ContractAddress) -> Span { + // call_contract_syscall is modified POC syscall to just return calldata it received + let value: Span = call_contract_syscall( + address, 0x1, array![0xa, 0xb, 0xc, 0xe].span(), + ).unwrap_syscall(); + value } } ``` diff --git a/bootloader_input.json b/bootloader_input.json index 6fa3e3b..6b72265 100644 --- a/bootloader_input.json +++ b/bootloader_input.json @@ -3,13 +3,15 @@ "prime": "0x800000000000011000000000000000000000000000000000000000000000001", "compiler_version": "2.6.3", "bytecode": [ + "0x40780017fff7fff", + "0x1", "0xa0680017fff8000", "0x7", "0x482680017ffa8000", "0x100000000000000000000000000000000", "0x400280007ff97fff", "0x10780017fff7fff", - "0xb6", + "0x128", "0x4825800180007ffa", "0x0", "0x400280007ff97fff", @@ -25,7 +27,7 @@ "0x480a7ffd7fff8000", "0x480680017fff8000", "0x0", - "0x480a7ffc7fff8000", + "0x480280007ffc8000", "0x10780017fff7fff", "0x8", "0x480a7ffc7fff8000", @@ -35,50 +37,95 @@ "0x480680017fff8000", "0x0", "0x20680017fff7ffe", - "0x20", - "0x40780017fff7fff", + "0xfd", + "0xa0680017fff8004", + "0xe", + "0x4824800180047ffe", + "0x800000000000000000000000000000000000000000000000000000000000000", + "0x484480017ffe8000", + "0x110000000000000000", + "0x48307ffe7fff8002", + "0x480080007ff67ffc", + "0x480080017ff57ffc", + "0x402480017ffb7ffd", + "0xffffffffffffffeeffffffffffffffff", + "0x400080027ff47ffd", + "0x10780017fff7fff", + "0xeb", + "0x484480017fff8001", + "0x8000000000000000000000000000000", + "0x48307fff80007ffd", + "0x480080007ff77ffd", + "0x480080017ff67ffd", + "0x402480017ffc7ffe", + "0xf8000000000000000000000000000000", + "0x400080027ff57ffe", + "0x482480017ff58000", + "0x3", + "0x48307ff680007ff7", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ff58000", + "0x1", + "0x48127ff57fff8000", + "0x480680017fff8000", + "0x0", + "0x480080007ff28000", + "0x10780017fff7fff", + "0x8", + "0x48127ff57fff8000", + "0x48127ff57fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0xbe", + "0x48307ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ffb8000", "0x1", - "0x48127ff97fff8000", - "0x48127ff77fff8000", - "0x48127ff97fff8000", - "0x48127ff97fff8000", "0x48127ffb7fff8000", - "0x48127ffa7fff8000", + "0x480680017fff8000", + "0x0", "0x480080007ff88000", - "0x1104800180018000", - "0xa0", - "0x20680017fff7ffa", - "0xb", - "0x48127ff87fff8000", - "0x48127ff87fff8000", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x48127ff97fff8000", "0x10780017fff7fff", - "0x14", - "0x48127ff87fff8000", - "0x48127ff87fff8000", - "0x480a7ffb7fff8000", + "0x8", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", "0x480680017fff8000", "0x1", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x48127ffa7fff8000", - "0x48127ff87fff8000", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x9b", + "0x48307ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ffb8000", "0x1", + "0x48127ffb7fff8000", "0x480680017fff8000", "0x0", + "0x480080007ff88000", + "0x10780017fff7fff", + "0x8", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", "0x480680017fff8000", "0x0", - "0x20680017fff7ffd", - "0x64", - "0x48307ffb80007ffc", + "0x20680017fff7ffe", + "0x78", + "0x48307ffc80007ffd", "0x20680017fff7fff", "0x4", "0x10780017fff7fff", @@ -88,8 +135,8 @@ "0x480680017fff8000", "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", "0x400080007ffe7fff", - "0x48127ff67fff8000", - "0x48127ff67fff8000", + "0x48127fed7fff8000", + "0x48127fe07fff8000", "0x480a7ffb7fff8000", "0x480680017fff8000", "0x1", @@ -98,48 +145,67 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x27a", + "0xf3", "0x482480017fff8000", - "0x279", + "0xf2", "0x480080007fff8000", "0xa0680017fff8000", "0x9", - "0x4824800180007ff4", - "0x254e", + "0x4824800180007fde", + "0x2aa8", "0x482480017fff8000", "0x100000000000000000000000000000000", - "0x400080007ff17fff", + "0x400080007fe87fff", "0x10780017fff7fff", - "0x34", - "0x4824800180007ff4", - "0x254e", - "0x400080007ff27fff", - "0x482480017ff28000", + "0x48", + "0x4824800180007fde", + "0x2aa8", + "0x400080007fe97fff", + "0x40780017fff7fff", "0x1", - "0x48127ff67fff8000", - "0x48127ff67fff8000", - "0x1104800180018000", - "0xb3", - "0x20680017fff7ffd", - "0x21", + "0x400080007fff7fed", + "0x400080017fff7ff2", + "0x400080027fff7ff7", + "0x480680017fff8000", + "0x1", + "0x48127ffe7fff8000", + "0x482480017ffd8000", + "0x3", + "0x482480017fe58000", + "0x1", + "0x480680017fff8000", + "0x43616c6c436f6e7472616374", + "0x400280007ffb7fff", + "0x400280017ffb7ff9", + "0x400280027ffb7fdd", + "0x400280037ffb7ffb", + "0x400280047ffb7ffc", + "0x400280057ffb7ffd", + "0x480280077ffb8000", + "0x20680017fff7fff", + "0x25", "0x40780017fff7fff", "0x1", - "0x48307ffd80007ffe", - "0x400080007ffe7fff", - "0x48127ffa7fff8000", - "0x48127fb67fff8000", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x482480017ff98000", + "0x480280087ffb8000", + "0x480280097ffb8000", + "0x48307ffe80007fff", + "0x400080007ffc7fff", + "0x48127ff97fff8000", + "0x480280067ffb8000", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x48127ff87fff8000", + "0x482480017ff78000", "0x1", + "0x402780017ffb8000", + "0xa", "0x1104800180018000", - "0x146", + "0x7a", "0x20680017fff7ffd", "0xa", "0x48127ffb7fff8000", "0x48127ffb7fff8000", - "0x480a7ffb7fff8000", + "0x480a80007fff8000", "0x480680017fff8000", "0x0", "0x48127ffa7fff8000", @@ -147,28 +213,29 @@ "0x208b7fff7fff7ffe", "0x48127ffb7fff8000", "0x48127ffb7fff8000", - "0x480a7ffb7fff8000", + "0x480a80007fff8000", "0x480680017fff8000", "0x1", "0x48127ffa7fff8000", "0x48127ffa7fff8000", "0x208b7fff7fff7ffe", - "0x48127ffc7fff8000", - "0x48127fb87fff8000", - "0x480a7ffb7fff8000", + "0x48127ffd7fff8000", + "0x480280067ffb8000", + "0x482680017ffb8000", + "0xa", "0x480680017fff8000", "0x1", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", + "0x480280087ffb8000", + "0x480280097ffb8000", "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x1", "0x480680017fff8000", "0x4f7574206f6620676173", "0x400080007ffe7fff", - "0x482480017fef8000", + "0x482480017fe68000", "0x1", - "0x48127fef7fff8000", + "0x48127fd97fff8000", "0x480a7ffb7fff8000", "0x480680017fff8000", "0x1", @@ -179,10 +246,10 @@ "0x40780017fff7fff", "0x1", "0x480680017fff8000", - "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x4661696c656420746f20646573657269616c697a6520706172616d202334", "0x400080007ffe7fff", - "0x48127ff77fff8000", - "0x48127ff77fff8000", + "0x48127fee7fff8000", + "0x48127fe17fff8000", "0x480a7ffb7fff8000", "0x480680017fff8000", "0x1", @@ -193,11 +260,10 @@ "0x40780017fff7fff", "0x1", "0x480680017fff8000", - "0x4f7574206f6620676173", + "0x4661696c656420746f20646573657269616c697a6520706172616d202333", "0x400080007ffe7fff", - "0x482680017ff98000", - "0x1", - "0x480a7ffa7fff8000", + "0x48127ff37fff8000", + "0x48127fe67fff8000", "0x480a7ffb7fff8000", "0x480680017fff8000", "0x1", @@ -205,676 +271,141 @@ "0x482480017ff98000", "0x1", "0x208b7fff7fff7ffe", - "0xa0680017fff8000", - "0x7", - "0x482680017ff88000", - "0xfffffffffffffffffffffffffffff6be", - "0x400280007ff77fff", - "0x10780017fff7fff", - "0x43", - "0x4825800180007ff8", - "0x942", - "0x400280007ff77fff", - "0x482680017ff78000", + "0x40780017fff7fff", "0x1", - "0x20780017fff7ffd", - "0xd", - "0x48127fff7fff8000", - "0x48127ffd7fff8000", "0x480680017fff8000", - "0x0", - "0x480a7ff97fff8000", - "0x480a7ffa7fff8000", - "0x480680017fff8000", - "0x0", + "0x4661696c656420746f20646573657269616c697a6520706172616d202332", + "0x400080007ffe7fff", + "0x48127ff87fff8000", + "0x48127feb7fff8000", "0x480a7ffb7fff8000", - "0x480a7ffc7fff8000", - "0x208b7fff7fff7ffe", - "0x48297ff980007ffa", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482680017ff98000", - "0x1", - "0x480a7ffa7fff8000", - "0x480680017fff8000", - "0x0", - "0x480280007ff98000", - "0x10780017fff7fff", - "0x8", - "0x480a7ff97fff8000", - "0x480a7ffa7fff8000", "0x480680017fff8000", "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0xf", - "0x400280007ffc7fff", - "0x48127ffa7fff8000", - "0x48127ff87fff8000", - "0x48127ffa7fff8000", "0x48127ffa7fff8000", - "0x480a7ffb7fff8000", - "0x482680017ffc8000", - "0x1", - "0x4825800180007ffd", + "0x482480017ff98000", "0x1", - "0x1104800180018000", - "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffc9", "0x208b7fff7fff7ffe", - "0x48127ffa7fff8000", - "0x48127ff87fff8000", - "0x480680017fff8000", - "0x0", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x480680017fff8000", + "0x482480017ff48000", + "0x3", + "0x10780017fff7fff", + "0x5", + "0x40780017fff7fff", + "0x6", + "0x48127ff47fff8000", + "0x40780017fff7fff", "0x1", "0x480680017fff8000", - "0x0", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x400080007ffe7fff", + "0x48127ffd7fff8000", + "0x48127fef7fff8000", + "0x480a7ffb7fff8000", "0x480680017fff8000", - "0x0", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x1", "0x480680017fff8000", "0x4f7574206f6620676173", "0x400080007ffe7fff", - "0x482680017ff78000", + "0x482680017ff98000", "0x1", - "0x480a7ff87fff8000", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", "0x480680017fff8000", "0x1", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x48127ff87fff8000", - "0x482480017ff78000", + "0x48127ffa7fff8000", + "0x482480017ff98000", "0x1", "0x208b7fff7fff7ffe", - "0x480a7ffb7fff8000", - "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", - "0x1104800180018000", - "0xe1", - "0x20680017fff7ffc", - "0x8f", - "0x48507ffd7ffd8000", - "0xa0680017fff8000", - "0x7", - "0x4824800180007ffe", - "0x100000000", - "0x400080007ff67fff", - "0x10780017fff7fff", - "0x78", - "0x482480017ffe8000", - "0xffffffffffffffffffffffff00000000", - "0x400080007ff67fff", - "0x48507ffb7ffb8000", - "0xa0680017fff8000", - "0x7", - "0x4824800180007ffe", - "0x100000000", - "0x400080017ff37fff", - "0x10780017fff7fff", - "0x5e", - "0x482480017ffe8000", - "0xffffffffffffffffffffffff00000000", - "0x400080017ff37fff", - "0x48507ff97ff98000", "0xa0680017fff8000", "0x7", - "0x4824800180007ffe", - "0x100000000", - "0x400080027ff07fff", - "0x10780017fff7fff", - "0x44", - "0x482480017ffe8000", - "0xffffffffffffffffffffffff00000000", - "0x400080027ff07fff", - "0xa0680017fff8000", - "0x8", - "0x48307ff97ff68000", - "0x4824800180007fff", - "0x100000000", - "0x400080037fed7fff", + "0x482680017ff98000", + "0xfffffffffffffffffffffffffffff722", + "0x400280007ff87fff", "0x10780017fff7fff", - "0x2a", - "0x48307ff97ff68001", - "0x4824800180007fff", - "0xffffffffffffffffffffffff00000000", - "0x400080037fed7ffe", - "0x482480017fed8000", - "0x4", - "0x48307ff980007ffe", + "0x2f", + "0x4825800180007ff9", + "0x8de", + "0x400280007ff87fff", + "0x482680017ff88000", + "0x1", + "0x48297ffa80007ffb", "0x20680017fff7fff", "0x4", "0x10780017fff7fff", - "0x10", - "0x40780017fff7fff", - "0x2", - "0x40780017fff7fff", + "0xa", + "0x482680017ffa8000", "0x1", + "0x480a7ffb7fff8000", "0x480680017fff8000", - "0x696e76616c69642076616c7565", - "0x400080007ffe7fff", - "0x48127ffa7fff8000", + "0x0", + "0x480a7ffa7fff8000", + "0x10780017fff7fff", + "0x8", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", "0x480680017fff8000", "0x1", - "0x48127ffc7fff8000", - "0x482480017ffb8000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x48127ff17fff8000", - "0x48127ff37fff8000", - "0x48127ff57fff8000", - "0x400080007ffc7ffd", - "0x400080017ffc7ffe", - "0x400080027ffc7fff", - "0x48127ffa7fff8000", "0x480680017fff8000", "0x0", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x3", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x4", - "0x40780017fff7fff", + "0x20680017fff7ffe", + "0xe", + "0x480080007fff8000", + "0x400280007ffd7fff", + "0x48127ff97fff8000", + "0x48127ff77fff8000", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x480a7ffc7fff8000", + "0x482680017ffd8000", "0x1", - "0x480680017fff8000", - "0x7533325f616464204f766572666c6f77", - "0x400080007ffe7fff", - "0x482480017fe78000", - "0x4", - "0x480680017fff8000", - "0x1", - "0x48127ffc7fff8000", - "0x482480017ffb8000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x7", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x7533325f6d756c204f766572666c6f77", - "0x400080007ffe7fff", - "0x482480017fe78000", - "0x3", - "0x480680017fff8000", - "0x1", - "0x48127ffc7fff8000", - "0x482480017ffb8000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0xa", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x7533325f6d756c204f766572666c6f77", - "0x400080007ffe7fff", - "0x482480017fe78000", - "0x2", - "0x480680017fff8000", - "0x1", - "0x48127ffc7fff8000", - "0x482480017ffb8000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0xd", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x7533325f6d756c204f766572666c6f77", - "0x400080007ffe7fff", - "0x482480017fe78000", - "0x1", - "0x480680017fff8000", - "0x1", - "0x48127ffc7fff8000", - "0x482480017ffb8000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x10", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7074696f6e3a3a756e77726170206661696c65642e", - "0x400080007ffe7fff", - "0x48127fe77fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffc7fff8000", - "0x482480017ffb8000", - "0x1", - "0x208b7fff7fff7ffe", - "0xa0680017fff8000", - "0x7", - "0x482680017ff98000", - "0xfffffffffffffffffffffffffffff722", - "0x400280007ff87fff", - "0x10780017fff7fff", - "0x2f", - "0x4825800180007ff9", - "0x8de", - "0x400280007ff87fff", - "0x482680017ff88000", - "0x1", - "0x48297ffa80007ffb", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482680017ffa8000", - "0x1", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x0", - "0x480a7ffa7fff8000", - "0x10780017fff7fff", - "0x8", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0xe", - "0x480080007fff8000", - "0x400280007ffd7fff", - "0x48127ff97fff8000", - "0x48127ff77fff8000", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x480a7ffc7fff8000", - "0x482680017ffd8000", - "0x1", - "0x1104800180018000", - "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffd7", - "0x208b7fff7fff7ffe", - "0x48127ffa7fff8000", - "0x48127ff87fff8000", - "0x480680017fff8000", - "0x0", - "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff88000", - "0x1", - "0x480a7ff97fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffb7fff8000", - "0x482480017ffa8000", - "0x1", - "0x208b7fff7fff7ffe", - "0x48297ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482680017ffc8000", - "0x1", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x0", - "0x480a7ffc7fff8000", - "0x10780017fff7fff", - "0x8", - "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0xad", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x12", - "0x4824800180007ffe", - "0x100000000", - "0x4844800180008002", - "0x8000000000000110000000000000000", - "0x4830800080017ffe", - "0x480280007ffb7fff", - "0x482480017ffe8000", - "0xefffffffffffffde00000000ffffffff", - "0x480280017ffb7fff", - "0x400280027ffb7ffb", - "0x402480017fff7ffb", - "0xffffffffffffffffffffffffffffffff", - "0x20680017fff7fff", - "0x96", - "0x402780017fff7fff", - "0x1", - "0x400280007ffb7ffe", - "0x482480017ffe8000", - "0xffffffffffffffffffffffff00000000", - "0x400280017ffb7fff", - "0x482680017ffb8000", - "0x2", - "0x48307ff880007ff9", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482480017ff78000", - "0x1", - "0x48127ff77fff8000", - "0x480680017fff8000", - "0x0", - "0x48127ff47fff8000", - "0x10780017fff7fff", - "0x8", - "0x48127ff77fff8000", - "0x48127ff77fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0x6b", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x12", - "0x4824800180007ffe", - "0x100000000", - "0x4844800180008002", - "0x8000000000000110000000000000000", - "0x4830800080017ffe", - "0x480080007ff57fff", - "0x482480017ffe8000", - "0xefffffffffffffde00000000ffffffff", - "0x480080017ff37fff", - "0x400080027ff27ffb", - "0x402480017fff7ffb", - "0xffffffffffffffffffffffffffffffff", - "0x20680017fff7fff", - "0x54", - "0x402780017fff7fff", - "0x1", - "0x400080007ff87ffe", - "0x482480017ffe8000", - "0xffffffffffffffffffffffff00000000", - "0x400080017ff77fff", - "0x482480017ff78000", - "0x2", - "0x48307ff880007ff9", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482480017ff78000", - "0x1", - "0x48127ff77fff8000", - "0x480680017fff8000", - "0x0", - "0x48127ff47fff8000", - "0x10780017fff7fff", - "0x8", - "0x48127ff77fff8000", - "0x48127ff77fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0x29", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x12", - "0x4824800180007ffe", - "0x100000000", - "0x4844800180008002", - "0x8000000000000110000000000000000", - "0x4830800080017ffe", - "0x480080007ff57fff", - "0x482480017ffe8000", - "0xefffffffffffffde00000000ffffffff", - "0x480080017ff37fff", - "0x400080027ff27ffb", - "0x402480017fff7ffb", - "0xffffffffffffffffffffffffffffffff", - "0x20680017fff7fff", - "0x14", - "0x402780017fff7fff", - "0x1", - "0x400080007ff87ffe", - "0x482480017ffe8000", - "0xffffffffffffffffffffffff00000000", - "0x400080017ff77fff", - "0x40780017fff7fff", - "0x5", - "0x482480017ff28000", - "0x2", - "0x48127ff37fff8000", - "0x48127ff37fff8000", - "0x480680017fff8000", - "0x0", - "0x48127fe27fff8000", - "0x48127fea7fff8000", - "0x48127ff27fff8000", - "0x208b7fff7fff7ffe", - "0x482480017ff28000", - "0x3", - "0x10780017fff7fff", - "0x5", - "0x40780017fff7fff", - "0x8", - "0x48127ff27fff8000", - "0x48127ff37fff8000", - "0x48127ff37fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x9", - "0x482480017fe98000", - "0x3", - "0x10780017fff7fff", - "0x5", - "0x40780017fff7fff", - "0x11", - "0x48127fe97fff8000", - "0x48127fea7fff8000", - "0x48127fea7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x12", - "0x482680017ffb8000", - "0x3", - "0x10780017fff7fff", - "0x5", - "0x40780017fff7fff", - "0x1a", - "0x480a7ffb7fff8000", - "0x48127fe17fff8000", - "0x48127fe17fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x208b7fff7fff7ffe", - "0x208b7fff7fff7ffe" - ], - "bytecode_segment_lengths": [ - 202, - 92, - 162, - 66, - 207 - ], - "hints": [ - [ - 0, - [ - { - "TestLessThanOrEqual": { - "lhs": { - "Immediate": "0x0" - }, - "rhs": { - "Deref": { - "register": "FP", - "offset": -6 - } - }, - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 33, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 80, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 99, - [ - { - "TestLessThanOrEqual": { - "lhs": { - "Immediate": "0x254e" - }, - "rhs": { - "Deref": { - "register": "AP", - "offset": -11 - } - }, - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 119, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 158, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 173, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 187, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], + "0x1104800180018000", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffd7", + "0x208b7fff7fff7ffe", + "0x48127ffa7fff8000", + "0x48127ff87fff8000", + "0x480680017fff8000", + "0x0", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff88000", + "0x1", + "0x480a7ff97fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffb7fff8000", + "0x482480017ffa8000", + "0x1", + "0x208b7fff7fff7ffe", + "0x208b7fff7fff7ffe" + ], + "bytecode_segment_lengths": [ + 318, + 67 + ], + "hints": [ [ - 202, + 2, [ { "TestLessThanOrEqual": { "lhs": { - "Immediate": "0x942" + "Immediate": "0x0" }, "rhs": { "Deref": { "register": "FP", - "offset": -8 + "offset": -6 } }, "dst": { @@ -886,20 +417,7 @@ ] ], [ - 274, - [ - { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 302, + 35, [ { "TestLessThan": { @@ -910,84 +428,67 @@ } }, "rhs": { - "Immediate": "0x100000000" + "Immediate": "0x800000000000000000000000000000000000000000000000000000000000000" }, "dst": { "register": "AP", - "offset": 0 + "offset": 4 } } } ] ], [ - 313, + 39, [ { - "TestLessThan": { - "lhs": { + "LinearSplit": { + "value": { "Deref": { "register": "AP", - "offset": -1 + "offset": 3 } }, - "rhs": { - "Immediate": "0x100000000" + "scalar": { + "Immediate": "0x110000000000000000" }, - "dst": { + "max_x": { + "Immediate": "0xffffffffffffffffffffffffffffffff" + }, + "x": { "register": "AP", - "offset": 0 + "offset": -2 + }, + "y": { + "register": "AP", + "offset": -1 } } } ] ], [ - 324, + 49, [ { - "TestLessThan": { - "lhs": { + "LinearSplit": { + "value": { "Deref": { "register": "AP", - "offset": -1 + "offset": -2 } }, - "rhs": { - "Immediate": "0x100000000" + "scalar": { + "Immediate": "0x8000000000000000000000000000000" }, - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 334, - [ - { - "TestLessThan": { - "lhs": { - "BinOp": { - "op": "Add", - "a": { - "register": "AP", - "offset": -9 - }, - "b": { - "Deref": { - "register": "AP", - "offset": -6 - } - } - } + "max_x": { + "Immediate": "0xffffffffffffffffffffffffffffffff" }, - "rhs": { - "Immediate": "0x100000000" + "x": { + "register": "AP", + "offset": -1 }, - "dst": { + "y": { "register": "AP", "offset": 0 } @@ -996,7 +497,7 @@ ] ], [ - 355, + 127, [ { "AllocSegment": { @@ -1009,10 +510,19 @@ ] ], [ - 367, + 146, [ { - "AllocSegment": { + "TestLessThanOrEqual": { + "lhs": { + "Immediate": "0x2aa8" + }, + "rhs": { + "Deref": { + "register": "AP", + "offset": -33 + } + }, "dst": { "register": "AP", "offset": 0 @@ -1022,7 +532,7 @@ ] ], [ - 384, + 158, [ { "AllocSegment": { @@ -1035,20 +545,22 @@ ] ], [ - 399, + 178, [ { - "AllocSegment": { - "dst": { - "register": "AP", - "offset": 0 + "SystemCall": { + "system": { + "Deref": { + "register": "FP", + "offset": -5 + } } } } ] ], [ - 414, + 181, [ { "AllocSegment": { @@ -1061,7 +573,7 @@ ] ], [ - 429, + 225, [ { "AllocSegment": { @@ -1074,7 +586,7 @@ ] ], [ - 444, + 240, [ { "AllocSegment": { @@ -1087,19 +599,10 @@ ] ], [ - 456, + 254, [ { - "TestLessThanOrEqual": { - "lhs": { - "Immediate": "0x8de" - }, - "rhs": { - "Deref": { - "register": "FP", - "offset": -7 - } - }, + "AllocSegment": { "dst": { "register": "AP", "offset": 0 @@ -1109,7 +612,7 @@ ] ], [ - 508, + 268, [ { "AllocSegment": { @@ -1122,25 +625,10 @@ ] ], [ - 544, + 289, [ { - "TestLessThan": { - "lhs": { - "BinOp": { - "op": "Add", - "a": { - "register": "AP", - "offset": -1 - }, - "b": { - "Immediate": "0x0" - } - } - }, - "rhs": { - "Immediate": "0x100000000" - }, + "AllocSegment": { "dst": { "register": "AP", "offset": 0 @@ -1150,111 +638,32 @@ ] ], [ - 548, + 303, [ { - "LinearSplit": { - "value": { - "Deref": { - "register": "AP", - "offset": -1 - } - }, - "scalar": { - "Immediate": "0x8000000000000110000000000000000" - }, - "max_x": { - "Immediate": "0xfffffffffffffffffffffffffffffffe" - }, - "x": { + "AllocSegment": { + "dst": { "register": "AP", "offset": 0 - }, - "y": { - "register": "AP", - "offset": 1 } } } ] ], [ - 590, + 318, [ { - "TestLessThan": { + "TestLessThanOrEqual": { "lhs": { - "BinOp": { - "op": "Add", - "a": { - "register": "AP", - "offset": -1 - }, - "b": { - "Immediate": "0x0" - } - } + "Immediate": "0x8de" }, "rhs": { - "Immediate": "0x100000000" - }, - "dst": { - "register": "AP", - "offset": 0 - } - } - } - ] - ], - [ - 594, - [ - { - "LinearSplit": { - "value": { "Deref": { - "register": "AP", - "offset": -1 - } - }, - "scalar": { - "Immediate": "0x8000000000000110000000000000000" - }, - "max_x": { - "Immediate": "0xfffffffffffffffffffffffffffffffe" - }, - "x": { - "register": "AP", - "offset": 0 - }, - "y": { - "register": "AP", - "offset": 1 - } - } - } - ] - ], - [ - 636, - [ - { - "TestLessThan": { - "lhs": { - "BinOp": { - "op": "Add", - "a": { - "register": "AP", - "offset": -1 - }, - "b": { - "Immediate": "0x0" - } + "register": "FP", + "offset": -7 } }, - "rhs": { - "Immediate": "0x100000000" - }, "dst": { "register": "AP", "offset": 0 @@ -1264,29 +673,13 @@ ] ], [ - 640, + 370, [ { - "LinearSplit": { - "value": { - "Deref": { - "register": "AP", - "offset": -1 - } - }, - "scalar": { - "Immediate": "0x8000000000000110000000000000000" - }, - "max_x": { - "Immediate": "0xfffffffffffffffffffffffffffffffe" - }, - "x": { + "AllocSegment": { + "dst": { "register": "AP", "offset": 0 - }, - "y": { - "register": "AP", - "offset": 1 } } } @@ -1295,178 +688,106 @@ ], "pythonic_hints": [ [ - 0, + 2, [ "memory[ap + 0] = 0 <= memory[fp + -6]" ] ], [ - 33, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 80, - [ - "memory[ap + 0] = segments.add()" - ] - ], - [ - 99, - [ - "memory[ap + 0] = 9550 <= memory[ap + -11]" - ] - ], - [ - 119, + 35, [ - "memory[ap + 0] = segments.add()" + "memory[ap + 4] = memory[ap + -1] < 3618502788666131106986593281521497120414687020801267626233049500247285301248" ] ], [ - 158, + 39, [ - "memory[ap + 0] = segments.add()" + "\n(value, scalar) = (memory[ap + 3], 313594649253062377472)\nx = min(value // scalar, 340282366920938463463374607431768211455)\ny = value - x * scalar\nmemory[ap + -2] = x\nmemory[ap + -1] = y\n" ] ], [ - 173, + 49, [ - "memory[ap + 0] = segments.add()" + "\n(value, scalar) = (memory[ap + -2], 10633823966279326983230456482242756608)\nx = min(value // scalar, 340282366920938463463374607431768211455)\ny = value - x * scalar\nmemory[ap + -1] = x\nmemory[ap + 0] = y\n" ] ], [ - 187, + 127, [ "memory[ap + 0] = segments.add()" ] ], [ - 202, + 146, [ - "memory[ap + 0] = 2370 <= memory[fp + -8]" + "memory[ap + 0] = 10920 <= memory[ap + -33]" ] ], [ - 274, + 158, [ "memory[ap + 0] = segments.add()" ] ], [ - 302, - [ - "memory[ap + 0] = memory[ap + -1] < 4294967296" - ] - ], - [ - 313, + 178, [ - "memory[ap + 0] = memory[ap + -1] < 4294967296" + "syscall_handler.syscall(syscall_ptr=memory[fp + -5])" ] ], [ - 324, - [ - "memory[ap + 0] = memory[ap + -1] < 4294967296" - ] - ], - [ - 334, - [ - "memory[ap + 0] = (memory[ap + -9] + memory[ap + -6]) % PRIME < 4294967296" - ] - ], - [ - 355, + 181, [ "memory[ap + 0] = segments.add()" ] ], [ - 367, + 225, [ "memory[ap + 0] = segments.add()" ] ], [ - 384, + 240, [ "memory[ap + 0] = segments.add()" ] ], [ - 399, + 254, [ "memory[ap + 0] = segments.add()" ] ], [ - 414, + 268, [ "memory[ap + 0] = segments.add()" ] ], [ - 429, + 289, [ "memory[ap + 0] = segments.add()" ] ], [ - 444, + 303, [ "memory[ap + 0] = segments.add()" ] ], [ - 456, + 318, [ "memory[ap + 0] = 2270 <= memory[fp + -7]" ] ], [ - 508, + 370, [ "memory[ap + 0] = segments.add()" ] - ], - [ - 544, - [ - "memory[ap + 0] = (memory[ap + -1] + 0) % PRIME < 4294967296" - ] - ], - [ - 548, - [ - "\n(value, scalar) = (memory[ap + -1], 10633823966279327296825105735305134080)\nx = min(value // scalar, 340282366920938463463374607431768211454)\ny = value - x * scalar\nmemory[ap + 0] = x\nmemory[ap + 1] = y\n" - ] - ], - [ - 590, - [ - "memory[ap + 0] = (memory[ap + -1] + 0) % PRIME < 4294967296" - ] - ], - [ - 594, - [ - "\n(value, scalar) = (memory[ap + -1], 10633823966279327296825105735305134080)\nx = min(value // scalar, 340282366920938463463374607431768211454)\ny = value - x * scalar\nmemory[ap + 0] = x\nmemory[ap + 1] = y\n" - ] - ], - [ - 636, - [ - "memory[ap + 0] = (memory[ap + -1] + 0) % PRIME < 4294967296" - ] - ], - [ - 640, - [ - "\n(value, scalar) = (memory[ap + -1], 10633823966279327296825105735305134080)\nx = min(value // scalar, 340282366920938463463374607431768211454)\ny = value - x * scalar\nmemory[ap + 0] = x\nmemory[ap + 1] = y\n" - ] ] ], "entry_points_by_type": { diff --git a/cairo0-bootloader/bootloader/contract/execute_entry_point.cairo b/cairo0-bootloader/bootloader/contract/execute_entry_point.cairo index 8628324..ebab159 100644 --- a/cairo0-bootloader/bootloader/contract/execute_entry_point.cairo +++ b/cairo0-bootloader/bootloader/contract/execute_entry_point.cairo @@ -7,12 +7,12 @@ from starkware.cairo.common.dict_access import DictAccess from starkware.cairo.common.find_element import find_element, search_sorted from starkware.cairo.common.math import assert_not_zero from starkware.cairo.common.registers import get_ap +from bootloader.contract.execute_syscalls import execute_syscalls from starkware.starknet.builtins.segment_arena.segment_arena import ( SegmentArenaBuiltin, validate_segment_arena, ) from starkware.starknet.common.syscalls import TxInfo as DeprecatedTxInfo -from starkware.starknet.core.os.block_context import BlockContext from starkware.starknet.core.os.builtins import ( BuiltinEncodings, BuiltinParams, @@ -31,19 +31,7 @@ from starkware.starknet.core.os.constants import ( ) from contract_class.compiled_class import CompiledClass, CompiledClassEntryPoint, CompiledClassFact from starkware.starknet.core.os.output import OsCarriedOutputs - -struct ExecutionInfo { - selector: felt, -} - -// Represents the execution context during the execution of contract code. -struct ExecutionContext { - entry_point_type: felt, - calldata_size: felt, - calldata: felt*, - // Additional information about the execution. - execution_info: ExecutionInfo*, -} +from bootloader.contract.execute_syscalls import ExecutionContext // Represents the arguments pushed to the stack before calling an entry point. struct EntryPointCallArguments { @@ -65,15 +53,11 @@ struct EntryPointReturnValues { // Performs a Cairo jump to the function 'execute_syscalls'. // This function's signature must match the signature of 'execute_syscalls'. -func call_execute_syscalls{ - range_check_ptr, - syscall_ptr: felt*, - builtin_ptrs: BuiltinPointers*, - contract_state_changes: DictAccess*, - contract_class_changes: DictAccess*, - outputs: OsCarriedOutputs*, -}(block_context: BlockContext*, execution_context: ExecutionContext*, syscall_ptr_end: felt*) { - %{ print("call_execute_syscalls") %} +func call_execute_syscalls{range_check_ptr, syscall_ptr: felt*, builtin_ptrs: BuiltinPointers*, dict_ptr: DictAccess*}( + execution_context: ExecutionContext*, syscall_ptr_end: felt* +) { + execute_syscalls(execution_context, syscall_ptr_end); + return (); } // Returns the CompiledClassEntryPoint, based on 'compiled_class' and 'execution_context'. @@ -128,10 +112,9 @@ func get_entry_point{range_check_ptr}( // and execution_context.execution_info.selector. // // Arguments: -// block_context - a global context that is fixed throughout the block. // execution_context - The context for the current execution. func execute_entry_point{ - range_check_ptr, builtin_ptrs: BuiltinPointers*, builtin_params: BuiltinParams* + range_check_ptr, builtin_ptrs: BuiltinPointers*, builtin_params: BuiltinParams*, dict_ptr: DictAccess* }(compiled_class: CompiledClass*, execution_context: ExecutionContext*) -> ( retdata_size: felt, retdata: felt* ) { @@ -158,7 +141,7 @@ func execute_entry_point{ print("contract_entry_point:" , ids.contract_entry_point) ids.syscall_ptr = segments.add() from bootloader.contract.syscall_handler import SyscallHandler - syscall_handler = SyscallHandler(segments=segments) + syscall_handler = SyscallHandler(segments=segments, dict_manager=__dict_manager) syscall_handler.set_syscall_ptr(syscall_ptr=ids.syscall_ptr) %} @@ -181,7 +164,7 @@ func execute_entry_point{ // Use tempvar to pass the rest of the arguments to contract_entry_point(). let current_ap = ap; tempvar args = EntryPointCallArguments( - gas_builtin=1000000, + gas_builtin=1000000000000, syscall_ptr=syscall_ptr, calldata_start=calldata_start, calldata_end=calldata_end, @@ -232,17 +215,16 @@ func execute_entry_point{ validate_segment_arena(segment_arena=current_segment_arena); let builtin_ptrs = return_builtin_ptrs; - // with syscall_ptr { - // call_execute_syscalls( - // block_context=block_context, - // execution_context=execution_context, - // syscall_ptr_end=entry_point_return_values.syscall_ptr, - // ); - // } + with syscall_ptr, dict_ptr { + call_execute_syscalls( + execution_context=execution_context, + syscall_ptr_end=entry_point_return_values.syscall_ptr, + ); + } %{ print(ids.entry_point_return_values.failure_flag) - for i in range(0, 4): + for i in range(0, 2): print(memory[ids.retdata_start + i]) %} diff --git a/cairo0-bootloader/bootloader/contract/execute_syscalls.cairo b/cairo0-bootloader/bootloader/contract/execute_syscalls.cairo new file mode 100644 index 0000000..4d194d2 --- /dev/null +++ b/cairo0-bootloader/bootloader/contract/execute_syscalls.cairo @@ -0,0 +1,130 @@ +from starkware.cairo.common.bool import FALSE +from starkware.cairo.common.cairo_builtins import BitwiseBuiltin +from starkware.cairo.common.cairo_secp.bigint import ( + bigint_to_uint256, + nondet_bigint3, + uint256_to_bigint, +) +from starkware.cairo.common.dict import dict_read, dict_update +from starkware.cairo.common.dict_access import DictAccess +from starkware.cairo.common.math import ( + assert_le, + assert_lt, + assert_nn, + assert_not_zero, + unsigned_div_rem, +) +from starkware.cairo.common.memcpy import memcpy +from starkware.cairo.common.segments import relocate_segment +from starkware.cairo.common.uint256 import Uint256, assert_uint256_lt, uint256_lt +from starkware.starknet.common.new_syscalls import ( + CALL_CONTRACT_SELECTOR, + CallContractRequest, + CallContractResponse, + RequestHeader, + ResponseHeader, + FailureReason, +) +from starkware.starknet.core.os.builtins import ( + BuiltinPointers, + NonSelectableBuiltins, + SelectableBuiltins, +) +from starkware.starknet.core.os.execution.deprecated_execute_syscalls import deploy_contract +from starkware.starknet.core.os.output import ( + MessageToL1Header, + OsCarriedOutputs, + os_carried_outputs_new, +) +from starkware.starknet.core.os.state.commitment import StateEntry + +struct ExecutionInfo { + selector: felt, +} + +// Represents the execution context during the execution of contract code. +struct ExecutionContext { + entry_point_type: felt, + calldata_size: felt, + calldata: felt*, + // Additional information about the execution. + execution_info: ExecutionInfo*, +} + +// Executes the system calls in syscall_ptr. +// The signature of the function 'call_execute_syscalls' must match this function's signature. +// +// Arguments: +// execution_context - The execution context in which the system calls need to be executed. +// syscall_ptr_end - a pointer to the end of the syscall segment. +func execute_syscalls{range_check_ptr, syscall_ptr: felt*, builtin_ptrs: BuiltinPointers*, dict_ptr: DictAccess*}( + execution_context: ExecutionContext*, syscall_ptr_end: felt* +) { + if (syscall_ptr == syscall_ptr_end) { + return (); + } + + tempvar selector = [syscall_ptr]; + + assert selector = CALL_CONTRACT_SELECTOR; + + execute_call_contract(caller_execution_context=execution_context); + return execute_syscalls(execution_context=execution_context, syscall_ptr_end=syscall_ptr_end); +} + +// Executes a syscall that calls another contract. +func execute_call_contract{range_check_ptr, syscall_ptr: felt*, builtin_ptrs: BuiltinPointers*, dict_ptr: DictAccess*}( + caller_execution_context: ExecutionContext* +) { + let request_header = cast(syscall_ptr, RequestHeader*); + let syscall_ptr = syscall_ptr + RequestHeader.SIZE; + + let call_contract_request = cast(syscall_ptr, CallContractRequest*); + let syscall_ptr = syscall_ptr + CallContractRequest.SIZE; + + %{ + print("call_contract_request", memory[ids.call_contract_request.calldata_start + 2]) + %} + + let (value) = dict_read(call_contract_request.calldata_start[2]); + + %{ + print("value", ids.value) + %} + + let response_header = cast(syscall_ptr, ResponseHeader*); + let syscall_ptr = syscall_ptr + ResponseHeader.SIZE; + + let call_contract_response = cast(syscall_ptr, CallContractResponse*); + let syscall_ptr = syscall_ptr + CallContractResponse.SIZE; + + %{ + print("call_contract_response", memory[ids.call_contract_response.retdata_start + 0]) + %} + + assert value = call_contract_response.retdata_start[0]; + + + return (); +} + +// Returns a failure response with a single felt. +@known_ap_change +func write_failure_response{syscall_ptr: felt*}(remaining_gas: felt, failure_felt: felt) { + let response_header = cast(syscall_ptr, ResponseHeader*); + // Advance syscall pointer to the response body. + let syscall_ptr = syscall_ptr + ResponseHeader.SIZE; + + // Write the response header. + assert [response_header] = ResponseHeader(gas=remaining_gas, failure_flag=1); + + let failure_reason: FailureReason* = cast(syscall_ptr, FailureReason*); + // Advance syscall pointer to the next syscall. + let syscall_ptr = syscall_ptr + FailureReason.SIZE; + + // Write the failure reason. + tempvar start = failure_reason.start; + assert start[0] = failure_felt; + assert failure_reason.end = start + 1; + return (); +} diff --git a/cairo0-bootloader/bootloader/contract/run_contract_bootloader.cairo b/cairo0-bootloader/bootloader/contract/run_contract_bootloader.cairo index f5453f5..fc20572 100644 --- a/cairo0-bootloader/bootloader/contract/run_contract_bootloader.cairo +++ b/cairo0-bootloader/bootloader/contract/run_contract_bootloader.cairo @@ -7,6 +7,7 @@ from starkware.cairo.common.cairo_builtins import ( EcOpBuiltin, ) from starkware.cairo.common.registers import get_fp_and_pc +from starkware.cairo.common.dict import dict_new from contract_class.compiled_class import CompiledClass from starkware.starknet.builtins.segment_arena.segment_arena import new_arena, SegmentArenaBuiltin from starkware.starknet.core.os.builtins import ( @@ -18,11 +19,8 @@ from starkware.starknet.core.os.builtins import ( SelectableBuiltins, update_builtin_ptrs, ) -from bootloader.contract.execute_entry_point import ( - execute_entry_point, - ExecutionContext, - ExecutionInfo, -) +from bootloader.contract.execute_entry_point import execute_entry_point +from bootloader.contract.execute_syscalls import ExecutionContext, ExecutionInfo from starkware.starknet.core.os.constants import ENTRY_POINT_TYPE_EXTERNAL // Loads the programs and executes them. @@ -93,13 +91,24 @@ func run_contract_bootloader{ local calldata: felt*; %{ ids.calldata = segments.add() %} - - assert calldata[0] = 0x3; - assert calldata[1] = 0x3; - assert calldata[2] = 0x4; - assert calldata[3] = 0x5; - local execution_info: ExecutionInfo = ExecutionInfo(selector=0x00e2054f8a912367e38a22ce773328ff8aabf8082c4120bad9ef085e1dbf29a7); + %{ initial_dict = {7: 9} %} + let (dict_ptr) = dict_new(); + + %{ + print("__dict_manager", type(__dict_manager)) + + print("dict_ptr", ids.dict_ptr.address_) + %} + + assert calldata[0] = 0x0; + assert calldata[1] = 0x15; + assert calldata[2] = 0x0; + assert calldata[3] = 0x7; + + local execution_info: ExecutionInfo = ExecutionInfo( + selector=0x00e2054f8a912367e38a22ce773328ff8aabf8082c4120bad9ef085e1dbf29a7 + ); local execution_context: ExecutionContext = ExecutionContext( entry_point_type=ENTRY_POINT_TYPE_EXTERNAL, @@ -108,7 +117,7 @@ func run_contract_bootloader{ execution_info=&execution_info, ); - with builtin_ptrs, builtin_params { + with builtin_ptrs, builtin_params, dict_ptr { let (retdata_size, retdata) = execute_entry_point(compiled_class, &execution_context); } diff --git a/cairo0-bootloader/bootloader/contract/syscall_handler.py b/cairo0-bootloader/bootloader/contract/syscall_handler.py index 3867364..f46d19e 100644 --- a/cairo0-bootloader/bootloader/contract/syscall_handler.py +++ b/cairo0-bootloader/bootloader/contract/syscall_handler.py @@ -1,11 +1,15 @@ -from typing import Iterable -from starkware.starknet.core.os.syscall_handler import ( - SyscallHandlerBase, - OsExecutionHelper, +from typing import ( + Dict, + Iterable, ) from starkware.cairo.lang.vm.relocatable import RelocatableValue, MaybeRelocatable from starkware.cairo.lang.vm.memory_segments import MemorySegmentManager - +from bootloader.contract.syscall_handler_base import SyscallHandlerBase +from starkware.cairo.common.structs import CairoStructProxy +from starkware.cairo.common.dict import DictManager +from starkware.starknet.business_logic.execution.objects import ( + CallResult, +) class SyscallHandler(SyscallHandlerBase): """ @@ -15,8 +19,13 @@ class SyscallHandler(SyscallHandlerBase): def __init__( self, segments: MemorySegmentManager, + dict_manager: DictManager, ): + print("init") super().__init__(segments=segments, initial_syscall_ptr=None) + self.syscall_counter: Dict[str, int] = {} + self.dict_manager = dict_manager + print("initialized") def set_syscall_ptr(self, syscall_ptr: RelocatableValue): assert self._syscall_ptr is None, "syscall_ptr is already set." @@ -27,54 +36,23 @@ def allocate_segment(self, data: Iterable[MaybeRelocatable]) -> RelocatableValue self.segments.write_arg(ptr=segment_start, arg=data) return segment_start - def _allocate_segment_for_retdata(self): - # Implementation here - pass - - def _call_contract_helper(self): - # Implementation here - pass - - def _count_syscall(self): - # Implementation here - pass - - def _deploy(self): - # Implementation here - pass - - def _emit_event(self): - # Implementation here - pass - - def _get_block_hash(self): - # Implementation here - pass - - def _get_execution_info_ptr(self): - # Implementation here - pass - - def _keccak(self): - # Implementation here - pass - - def _replace_class(self): - # Implementation here - pass + def _allocate_segment_for_retdata(self, retdata: Iterable[int]) -> RelocatableValue: + return self.allocate_segment(data=retdata) - def _send_message_to_l1(self): - # Implementation here - pass + def _call_contract_helper( + self, request: CairoStructProxy, syscall_name: str + ) -> CallResult: + calldata = self._get_felt_range( + start_addr=request.calldata_start, end_addr=request.calldata_end + ) - def _storage_read(self): - # Implementation here - pass + dictionary = self.dict_manager.get_dict(RelocatableValue.from_tuple([calldata[0], calldata[1]])) - def _storage_write(self): - # Implementation here - pass + print("dictionary", dictionary) - def current_block_number(self): - # Implementation here - pass + print("calldata", calldata) + return CallResult( + gas_consumed=0, + failure_flag=0, + retdata=[int(dictionary[calldata[2]])], + ) \ No newline at end of file diff --git a/cairo0-bootloader/bootloader/contract/syscall_handler_base.py b/cairo0-bootloader/bootloader/contract/syscall_handler_base.py new file mode 100644 index 0000000..a522b50 --- /dev/null +++ b/cairo0-bootloader/bootloader/contract/syscall_handler_base.py @@ -0,0 +1,198 @@ +from typing import ( + Any, List, + Dict, + Iterable, + Optional, + Tuple, +) +import cachetools +from starkware.starknet.core.os.syscall_handler import ( + SyscallInfo, +) +SyscallFullResponse = Tuple[tuple, tuple] # Response header + specific syscall response. +import functools +from starkware.cairo.common.structs import CairoStructProxy +from abc import ABC, abstractmethod +from starkware.cairo.lang.vm.relocatable import RelocatableValue, MaybeRelocatable +from starkware.cairo.lang.vm.memory_segments import MemorySegmentManager +from starkware.starknet.definitions.error_codes import CairoErrorCode +from starkware.starknet.core.os.syscall_utils import ( + STARKNET_SYSCALLS_COMPILED_PATH, + cast_to_int, + get_selector_from_program, + get_syscall_structs, + load_program, + validate_runtime_request_type, +) +from starkware.starknet.core.os.syscall_utils import ( + STARKNET_SYSCALLS_COMPILED_PATH, + cast_to_int, + get_selector_from_program, + get_syscall_structs, + load_program, + validate_runtime_request_type, +) +from starkware.starknet.business_logic.execution.objects import ( + CallResult, +) + +class SyscallHandlerBase(ABC): + def __init__( + self, + segments: MemorySegmentManager, + initial_syscall_ptr: Optional[RelocatableValue], + ): + # Static syscall information. + self.structs = get_syscall_structs() + self.selector_to_syscall_info = self.get_selector_to_syscall_info() + + # Memory segments of the running program. + self.segments = segments + # Current syscall pointer; updated internally during the call execution. + self._syscall_ptr = initial_syscall_ptr + + @classmethod + @cachetools.cached(cache={}) + def get_selector_to_syscall_info(cls) -> Dict[int, SyscallInfo]: + structs = get_syscall_structs() + syscalls_program = load_program(path=STARKNET_SYSCALLS_COMPILED_PATH) + get_selector = functools.partial( + get_selector_from_program, syscalls_program=syscalls_program + ) + return { + get_selector("call_contract"): SyscallInfo( + name="call_contract", + execute_callback=cls.call_contract, + request_struct=structs.CallContractRequest, + ), + } + + @property + def syscall_ptr(self) -> RelocatableValue: + assert ( + self._syscall_ptr is not None + ), "syscall_ptr must be set before using the SyscallHandler." + return self._syscall_ptr + + def syscall(self, syscall_ptr: RelocatableValue): + """ + Executes the selected system call. + """ + self._validate_syscall_ptr(actual_syscall_ptr=syscall_ptr) + request_header = self._read_and_validate_request(request_struct=self.structs.RequestHeader) + + # Validate syscall selector and request. + selector = cast_to_int(request_header.selector) + syscall_info = self.selector_to_syscall_info.get(selector) + assert ( + syscall_info is not None + ), f"Unsupported syscall selector {bytes.fromhex(hex(selector)[2:])!r}" + print("syscall_info", syscall_info.name) + request = self._read_and_validate_request(request_struct=syscall_info.request_struct) + response_header, response = syscall_info.execute_callback(self, request) + + print("response_header", response_header) + print("response", response) + + # Write response to the syscall segment. + self._write_response(response=response_header) + self._write_response(response=response) + + # Syscalls. + + def call_contract(self, request: CairoStructProxy) -> SyscallFullResponse: + return self.call_contract_helper( + request=request, syscall_name="call_contract" + ) + + def call_contract_helper( + self, request: CairoStructProxy, syscall_name: str + ) -> SyscallFullResponse: + result = self._call_contract_helper(request=request, syscall_name=syscall_name + ) + + response_header = self.structs.ResponseHeader( + gas=1000000000000, failure_flag=result.failure_flag + ) + retdata_start = self._allocate_segment_for_retdata(retdata=result.retdata) + retdata_end = retdata_start + len(result.retdata) + if response_header.failure_flag == 0: + response = self.structs.CallContractResponse( + retdata_start=retdata_start, retdata_end=retdata_end + ) + else: + response = self.structs.FailureReason(start=retdata_start, end=retdata_end) + + return response_header, response + + # Application-specific syscall implementation. + + @abstractmethod + def _call_contract_helper( + self, request: CairoStructProxy, syscall_name: str + ) -> CallResult: + """ + Returns the call's result. + + syscall_name can be "call_contract" or "library_call". + """ + + # Internal utilities. + + def _get_felt_range(self, start_addr: Any, end_addr: Any) -> List[int]: + assert isinstance(start_addr, RelocatableValue) + assert isinstance(end_addr, RelocatableValue) + assert start_addr.segment_index == end_addr.segment_index, ( + "Inconsistent start and end segment indices " + f"({start_addr.segment_index} != {end_addr.segment_index})." + ) + + assert start_addr.offset <= end_addr.offset, ( + "The start offset cannot be greater than the end offset" + f"({start_addr.offset} > {end_addr.offset})." + ) + + size = end_addr.offset - start_addr.offset + return self.segments.memory.get_range_as_ints(addr=start_addr, size=size) + + def _handle_failure(self, final_gas: int, error_code: CairoErrorCode) -> SyscallFullResponse: + response_header = self.structs.ResponseHeader(gas=final_gas, failure_flag=1) + data = [error_code.to_felt()] + start = self.allocate_segment(data=data) + failure_reason = self.structs.FailureReason(start=start, end=start + len(data)) + + return response_header, failure_reason + + @abstractmethod + def allocate_segment(self, data: Iterable[MaybeRelocatable]) -> RelocatableValue: + """ + Allocates and returns a new (read-only) segment with the given data. + Note that unlike MemorySegmentManager.write_arg, this function doesn't work well with + recursive input - call allocate_segment for the inner items if needed. + """ + + @abstractmethod + def _allocate_segment_for_retdata(self, retdata: Iterable[int]) -> RelocatableValue: + """ + Allocates and returns a new (read-only) segment with the given retdata. + """ + + def _validate_syscall_ptr(self, actual_syscall_ptr: RelocatableValue): + assert ( + actual_syscall_ptr == self.syscall_ptr + ), f"Bad syscall_ptr, Expected {self.syscall_ptr}, got {actual_syscall_ptr}." + + def _read_and_validate_request(self, request_struct: CairoStructProxy) -> CairoStructProxy: + request = self._read_request(request_struct=request_struct) + validate_runtime_request_type(request_values=request, request_struct=request_struct) + return request + + def _read_request(self, request_struct: CairoStructProxy) -> CairoStructProxy: + request = request_struct.from_ptr(memory=self.segments.memory, addr=self.syscall_ptr) + # Advance syscall pointer. + self._syscall_ptr = self.syscall_ptr + request_struct.size + return request + + def _write_response(self, response: tuple): + # Write response and update syscall pointer. + self._syscall_ptr = self.segments.write_arg(ptr=self.syscall_ptr, arg=response) diff --git a/cairo0-bootloader/setup.py b/cairo0-bootloader/setup.py index 52dc298..6905b1f 100644 --- a/cairo0-bootloader/setup.py +++ b/cairo0-bootloader/setup.py @@ -13,7 +13,7 @@ "bootloader.recursive": ["*.cairo", "*/*.cairo"], "bootloader.starknet_with_keccak": ["*.cairo", "*/*.cairo"], "bootloader.starknet": ["*.cairo", "*/*.cairo"], - "bootloader.contract": ["*.cairo", "*/*.cairo"], + "bootloader.contract": ["*.cairo", "*/*.cairo", "*.json"], "bootloader": ["*.cairo", "*/*.cairo"], "builtin_selection": ["*.cairo", "*/*.cairo"], "common.builtin_poseidon": ["*.cairo", "*/*.cairo"], diff --git a/contract/src/lib.cairo b/contract/src/lib.cairo index 853ec8a..c997544 100644 --- a/contract/src/lib.cairo +++ b/contract/src/lib.cairo @@ -1,41 +1,17 @@ -#[starknet::interface] -pub trait IHelloBootloader { - fn main(ref self: TContractState, input: Array) -> Array; -} - #[starknet::contract] -mod HelloBootloader { - #[derive(Drop, Serde)] - struct Input { - a: u32, - b: u32, - c: u32, - } - - #[derive(Drop, Serde)] - struct Output { - a_2: u32, - b_2: u32, - c_2: u32, - } +mod Factorial { + use starknet::{ContractAddress, SyscallResult, SyscallResultTrait}; + use starknet::syscalls::call_contract_syscall; #[storage] - struct Storage {} - - #[abi(embed_v0)] - impl HelloBootloaderImpl of super::IHelloBootloader { - fn main(ref self: ContractState, input: Array) -> Array { - let mut input_span = input.span(); - let input = Serde::::deserialize(ref input_span).unwrap(); - - let a_2 = input.a * input.a; - let b_2 = input.b * input.b; - let c_2 = input.c * input.c; - assert(a_2 + b_2 == c_2, 'invalid value'); + struct Storage{} - let mut output = array![]; - Output { a_2, b_2, c_2, }.serialize(ref output); - output - } + #[external(v0)] + fn main(ref self: ContractState, address: ContractAddress) -> Span { + // call_contract_syscall is modified POC syscall to just return calldata it received + let value: Span = call_contract_syscall( + address, 0x1, array![0xa, 0xb, 0xc, 0xe].span(), + ).unwrap_syscall(); + value } -} +} \ No newline at end of file