Skip to content

Commit cdb19fe

Browse files
committed
Add meta_tx_v0 syscall.
1 parent f090949 commit cdb19fe

File tree

7 files changed

+400
-37
lines changed

7 files changed

+400
-37
lines changed

examples/erc20.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,17 @@ impl StarknetSyscallHandler for SyscallHandler {
282282
) -> SyscallResult<Felt> {
283283
unimplemented!()
284284
}
285+
286+
fn meta_tx_v0(
287+
&mut self,
288+
_address: Felt,
289+
_entry_point_selector: Felt,
290+
_calldata: &[Felt],
291+
_signature: &[Felt],
292+
_remaining_gas: &mut u64,
293+
) -> SyscallResult<Vec<Felt>> {
294+
unimplemented!()
295+
}
285296
}
286297

287298
fn main() {

examples/starknet.rs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,34 @@ impl StarknetSyscallHandler for SyscallHandler {
308308
unimplemented!()
309309
}
310310

311+
fn sha256_process_block(
312+
&mut self,
313+
_state: &mut [u32; 8],
314+
_block: &[u32; 16],
315+
_remaining_gas: &mut u64,
316+
) -> SyscallResult<()> {
317+
unimplemented!()
318+
}
319+
320+
fn get_class_hash_at(
321+
&mut self,
322+
_contract_address: Felt,
323+
_remaining_gas: &mut u64,
324+
) -> SyscallResult<Felt> {
325+
unimplemented!()
326+
}
327+
328+
fn meta_tx_v0(
329+
&mut self,
330+
_address: Felt,
331+
_entry_point_selector: Felt,
332+
_calldata: &[Felt],
333+
_signature: &[Felt],
334+
_remaining_gas: &mut u64,
335+
) -> SyscallResult<Vec<Felt>> {
336+
unimplemented!()
337+
}
338+
311339
#[cfg(feature = "with-cheatcode")]
312340
fn cheatcode(&mut self, selector: Felt, input: &[Felt]) -> Vec<Felt> {
313341
let selector_bytes = selector.to_bytes_be();
@@ -399,23 +427,6 @@ impl StarknetSyscallHandler for SyscallHandler {
399427
_ => vec![],
400428
}
401429
}
402-
403-
fn sha256_process_block(
404-
&mut self,
405-
_state: &mut [u32; 8],
406-
_block: &[u32; 16],
407-
_remaining_gas: &mut u64,
408-
) -> SyscallResult<()> {
409-
unimplemented!()
410-
}
411-
412-
fn get_class_hash_at(
413-
&mut self,
414-
_contract_address: Felt,
415-
_remaining_gas: &mut u64,
416-
) -> SyscallResult<Felt> {
417-
unimplemented!()
418-
}
419430
}
420431

421432
fn main() {

src/libfuncs/starknet.rs

Lines changed: 218 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ pub fn build<'ctx, 'this>(
127127
StarknetConcreteLibfunc::LibraryCall(info) => {
128128
build_library_call(context, registry, entry, location, helper, metadata, info)
129129
}
130+
StarknetConcreteLibfunc::MetaTxV0(info) => {
131+
build_meta_tx_v0(context, registry, entry, location, helper, metadata, info)
132+
}
130133
StarknetConcreteLibfunc::ReplaceClass(info) => {
131134
build_replace_class(context, registry, entry, location, helper, metadata, info)
132135
}
@@ -139,9 +142,6 @@ pub fn build<'ctx, 'this>(
139142
StarknetConcreteLibfunc::Sha256ProcessBlock(info) => build_sha256_process_block_syscall(
140143
context, registry, entry, location, helper, metadata, info,
141144
),
142-
StarknetConcreteLibfunc::MetaTxV0(_) => {
143-
todo!("Implement MetaTxV0 libfunc");
144-
}
145145
#[cfg(feature = "with-cheatcode")]
146146
StarknetConcreteLibfunc::Testing(TestingConcreteLibfunc::Cheatcode(info)) => {
147147
self::testing::build(context, registry, entry, location, helper, metadata, info)
@@ -2123,6 +2123,221 @@ pub fn build_library_call<'ctx, 'this>(
21232123
Ok(())
21242124
}
21252125

2126+
pub fn build_meta_tx_v0<'ctx, 'this>(
2127+
context: &'ctx Context,
2128+
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
2129+
entry: &'this Block<'ctx>,
2130+
location: Location<'ctx>,
2131+
helper: &LibfuncHelper<'ctx, 'this>,
2132+
metadata: &mut MetadataStorage,
2133+
info: &SignatureOnlyConcreteLibfunc,
2134+
) -> Result<()> {
2135+
// pub extern fn call_contract_syscall(
2136+
// address: ContractAddress,
2137+
// entry_point_selector: felt252,
2138+
// calldata: Span<felt252>,
2139+
// ) -> SyscallResult<Span<felt252>> implicits(GasBuiltin, System) nopanic;
2140+
//
2141+
// extern fn meta_tx_v0_syscall(
2142+
// address: ContractAddress,
2143+
// entry_point_selector: felt252,
2144+
// calldata: Span<felt252>,
2145+
// signature: Span<felt252>,
2146+
// ) -> SyscallResult<Span<felt252>> implicits(GasBuiltin, System) nopanic;
2147+
2148+
// Extract self pointer.
2149+
let ptr = entry.load(
2150+
context,
2151+
location,
2152+
entry.arg(1)?,
2153+
llvm::r#type::pointer(context, 0),
2154+
)?;
2155+
2156+
// Allocate space for the return value.
2157+
let (result_layout, (result_tag_ty, result_tag_layout), variant_tys) =
2158+
crate::types::r#enum::get_type_for_variants(
2159+
context,
2160+
helper,
2161+
registry,
2162+
metadata,
2163+
&[
2164+
info.branch_signatures()[0].vars[2].ty.clone(),
2165+
info.branch_signatures()[1].vars[2].ty.clone(),
2166+
],
2167+
)?;
2168+
2169+
let result_ptr = helper.init_block().alloca1(
2170+
context,
2171+
location,
2172+
llvm::r#type::r#struct(
2173+
context,
2174+
&[
2175+
result_tag_ty,
2176+
llvm::r#type::array(
2177+
IntegerType::new(context, 8).into(),
2178+
(result_layout.size() - 1).try_into()?,
2179+
),
2180+
],
2181+
false,
2182+
),
2183+
result_layout.align(),
2184+
)?;
2185+
2186+
// Allocate space and write the current gas.
2187+
let (gas_ty, gas_layout) = registry.build_type_with_layout(
2188+
context,
2189+
helper,
2190+
metadata,
2191+
&info.param_signatures()[0].ty,
2192+
)?;
2193+
let gas_builtin_ptr =
2194+
helper
2195+
.init_block()
2196+
.alloca1(context, location, gas_ty, gas_layout.align())?;
2197+
entry.store(context, location, gas_builtin_ptr, entry.arg(0)?)?;
2198+
2199+
// Allocate `address` argument and write the value.
2200+
let address_arg_ptr = helper.init_block().alloca_int(context, location, 252)?;
2201+
entry.store(context, location, address_arg_ptr, entry.arg(2)?)?;
2202+
2203+
// Allocate `entry_point_selector` argument and write its value.
2204+
let entry_point_selector_arg_ptr = helper.init_block().alloca_int(context, location, 252)?;
2205+
entry.store(
2206+
context,
2207+
location,
2208+
entry_point_selector_arg_ptr,
2209+
entry.arg(3)?,
2210+
)?;
2211+
2212+
// Allocate `calldata` argument and write the value.
2213+
let calldata_arg_ty = llvm::r#type::r#struct(
2214+
context,
2215+
&[llvm::r#type::r#struct(
2216+
context,
2217+
&[
2218+
llvm::r#type::pointer(context, 0),
2219+
IntegerType::new(context, 32).into(),
2220+
IntegerType::new(context, 32).into(),
2221+
IntegerType::new(context, 32).into(),
2222+
],
2223+
false,
2224+
)],
2225+
false,
2226+
);
2227+
let calldata_arg_ptr = helper.init_block().alloca1(
2228+
context,
2229+
location,
2230+
calldata_arg_ty,
2231+
get_integer_layout(64).align(),
2232+
)?;
2233+
entry.store(context, location, calldata_arg_ptr, entry.arg(4)?)?;
2234+
2235+
// Allocate `signature` argument and write the value.
2236+
let signature_arg_ty = calldata_arg_ty;
2237+
let signature_arg_ptr = helper.init_block().alloca1(
2238+
context,
2239+
location,
2240+
signature_arg_ty,
2241+
get_integer_layout(64).align(),
2242+
)?;
2243+
entry.store(context, location, signature_arg_ptr, entry.arg(5)?)?;
2244+
2245+
// Extract function pointer.
2246+
let fn_ptr = entry.gep(
2247+
context,
2248+
location,
2249+
entry.arg(1)?,
2250+
&[GepIndex::Const(
2251+
StarknetSyscallHandlerCallbacks::<()>::META_TX_V0.try_into()?,
2252+
)],
2253+
llvm::r#type::pointer(context, 0),
2254+
)?;
2255+
let fn_ptr = entry.load(context, location, fn_ptr, llvm::r#type::pointer(context, 0))?;
2256+
2257+
entry.append_operation(
2258+
OperationBuilder::new("llvm.call", location)
2259+
.add_operands(&[
2260+
fn_ptr,
2261+
result_ptr,
2262+
ptr,
2263+
gas_builtin_ptr,
2264+
address_arg_ptr,
2265+
entry_point_selector_arg_ptr,
2266+
calldata_arg_ptr,
2267+
signature_arg_ptr,
2268+
])
2269+
.build()?,
2270+
);
2271+
2272+
let result = entry.load(
2273+
context,
2274+
location,
2275+
result_ptr,
2276+
llvm::r#type::r#struct(
2277+
context,
2278+
&[
2279+
result_tag_ty,
2280+
llvm::r#type::array(
2281+
IntegerType::new(context, 8).into(),
2282+
(result_layout.size() - 1).try_into()?,
2283+
),
2284+
],
2285+
false,
2286+
),
2287+
)?;
2288+
let result_tag = entry.extract_value(
2289+
context,
2290+
location,
2291+
result,
2292+
IntegerType::new(context, 1).into(),
2293+
0,
2294+
)?;
2295+
2296+
let payload_ok = {
2297+
let ptr = entry.gep(
2298+
context,
2299+
location,
2300+
result_ptr,
2301+
&[GepIndex::Const(
2302+
result_tag_layout.extend(variant_tys[0].1)?.1.try_into()?,
2303+
)],
2304+
IntegerType::new(context, 8).into(),
2305+
)?;
2306+
entry.load(context, location, ptr, variant_tys[0].0)?
2307+
};
2308+
let payload_err = {
2309+
let ptr = entry.gep(
2310+
context,
2311+
location,
2312+
result_ptr,
2313+
&[GepIndex::Const(
2314+
result_tag_layout.extend(variant_tys[1].1)?.1.try_into()?,
2315+
)],
2316+
IntegerType::new(context, 8).into(),
2317+
)?;
2318+
entry.load(context, location, ptr, variant_tys[1].0)?
2319+
};
2320+
2321+
let remaining_gas = entry.load(
2322+
context,
2323+
location,
2324+
gas_builtin_ptr,
2325+
IntegerType::new(context, 64).into(),
2326+
)?;
2327+
2328+
entry.append_operation(helper.cond_br(
2329+
context,
2330+
result_tag,
2331+
[1, 0],
2332+
[
2333+
&[remaining_gas, entry.arg(1)?, payload_err],
2334+
&[remaining_gas, entry.arg(1)?, payload_ok],
2335+
],
2336+
location,
2337+
));
2338+
Ok(())
2339+
}
2340+
21262341
pub fn build_replace_class<'ctx, 'this>(
21272342
context: &'ctx Context,
21282343
registry: &ProgramRegistry<CoreType, CoreLibfunc>,

0 commit comments

Comments
 (0)