diff --git a/cli/src/runner.rs b/cli/src/runner.rs index 8a8e2ff56..1d1dc5da3 100644 --- a/cli/src/runner.rs +++ b/cli/src/runner.rs @@ -70,7 +70,7 @@ pub fn tapes_to_runtime_arguments( .call_tape .writer .iter() - .map(|msg| msg.callee) + .map(|msg| msg.callee.0) .collect::>() .into_iter() .collect_vec(); diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 66c032d25..df5f63081 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -621,6 +621,18 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +[[package]] +name = "selfcaller" +version = "0.1.0" +dependencies = [ + "hex", + "mozak-sdk", + "rand", + "rand_chacha", + "rkyv", + "rkyv_derive", +] + [[package]] name = "serde" version = "1.0.198" diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 891ce1a5d..7629a4e01 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -16,6 +16,7 @@ members = [ "token", "wallet", "inputtape", + "selfcaller", ] resolver = "2" diff --git a/examples/inputtape/main_native.rs b/examples/inputtape/main_native.rs index e1a6e07ec..7eede1b77 100644 --- a/examples/inputtape/main_native.rs +++ b/examples/inputtape/main_native.rs @@ -2,7 +2,9 @@ #![allow(unused_attributes)] mod core_logic; -use mozak_sdk::common::types::{Poseidon2Hash, ProgramIdentifier}; +use mozak_sdk::common::types::{ + Poseidon2Hash, ProgramIdentifier, SelfCallExtendedProgramIdentifier, SelfCallExtensionFlag, +}; use crate::core_logic::{dispatch, MethodArgs}; @@ -12,7 +14,10 @@ fn main() { let buf1 = Poseidon2Hash::new_from_rand_seed(2).inner(); let buf2 = buf1.iter().map(|x| x.wrapping_add(1)).collect::>(); - mozak_sdk::add_identity(token_program); // Manual override for `IdentityStack` + mozak_sdk::add_identity(SelfCallExtendedProgramIdentifier( + token_program, + SelfCallExtensionFlag::default(), + )); // Manual override for `IdentityStack` let _ = mozak_sdk::write(&mozak_sdk::InputTapeType::PublicTape, &buf1); let _ = mozak_sdk::write(&mozak_sdk::InputTapeType::PrivateTape, &buf2[..]); mozak_sdk::rm_identity(); // Manual override for `IdentityStack` diff --git a/examples/selfcaller/Cargo.toml b/examples/selfcaller/Cargo.toml new file mode 100644 index 000000000..fc9550fb5 --- /dev/null +++ b/examples/selfcaller/Cargo.toml @@ -0,0 +1,34 @@ +[package] +edition = "2021" +name = "selfcaller" +version = "0.1.0" + +[features] +native = [] + +[dependencies] +mozak-sdk = { path = "../../sdk" } +rkyv = { version = "=0.8.0-alpha.1", default-features = false, features = ["pointer_width_32", "alloc"] } +rkyv_derive = "=0.8.0-alpha.1" + +[target.'cfg(not(target_os="mozakvm"))'.dependencies] +hex = "0.4" +rand = "0.8" +rand_chacha = "0.3" + +[[bin]] +name = "selfcallerbin" +path = "main_mozak.rs" + +[[bin]] +name = "selfcaller-native" +path = "main_native.rs" +required-features = ["native"] + +[lib] +name = "selfcaller" +path = "core_logic.rs" + +# The following is read by `run_examples.py` +[package.metadata.mozak] +example_program_id = "MZK-5b7b6135be198533f7c7ec46651216b762e6d47e69b408d1bc79d641f9ae06de" diff --git a/examples/selfcaller/README.md b/examples/selfcaller/README.md new file mode 100644 index 000000000..3a73aa71d --- /dev/null +++ b/examples/selfcaller/README.md @@ -0,0 +1,34 @@ +# To run + +## Native + +To run on your system, use the following command (kindly change [target triple](https://doc.rust-lang.org/cargo/appendix/glossary.html#target) as per your machine's architecture): + +```sh +# from project root +cargo run --release --features="native" --bin selfcaller-native --target aarch64-apple-darwin +``` + +This produces the `SystemTape` in both binary and debug formats. + +## Mozak-VM + +First, build the mozakvm binary: + +```sh +# inside examples directory +cargo build --release --bin selfcallerbin +``` + +Test the ELF in mozak-vm using the below command. Note that you must run +the native execution above to produce the system tape prior to running this. + +```sh +# from project root +MOZAK_STARK_DEBUG=true \ + cargo run --bin mozak-cli -- prove-and-verify -vvv \ + examples/target/riscv32im-mozak-mozakvm-elf/release/selfcallerbin \ + --system-tape examples/selfcaller.tape.json \ + --self-prog-id \ + MZK-5b7b6135be198533f7c7ec46651216b762e6d47e69b408d1bc79d641f9ae06de; +``` diff --git a/examples/selfcaller/core_logic.rs b/examples/selfcaller/core_logic.rs new file mode 100644 index 000000000..64259df74 --- /dev/null +++ b/examples/selfcaller/core_logic.rs @@ -0,0 +1,42 @@ +#![feature(restricted_std)] +#![allow(unused_attributes)] +extern crate alloc; + +use mozak_sdk::common::types::ProgramIdentifier; +use rkyv::{Archive, Deserialize, Serialize}; + +#[derive(Archive, Deserialize, Serialize, PartialEq, Eq, Clone)] +#[cfg_attr(not(target_os = "mozakvm"), derive(Debug))] +pub enum MethodArgs { + SelfCall(ProgramIdentifier, u8), +} + +#[derive(Archive, Debug, Deserialize, Serialize, PartialEq, Eq, Clone)] +pub enum MethodReturns { + SelfCall(u8), +} + +// TODO: Remove later +impl Default for MethodReturns { + fn default() -> Self { Self::SelfCall(0) } +} + +#[allow(clippy::unit_arg)] +pub fn dispatch(args: MethodArgs) -> MethodReturns { + match args { + MethodArgs::SelfCall(self_id, counter) => self_call(self_id, counter), + } +} + +pub fn self_call(self_id: ProgramIdentifier, counter: u8) -> MethodReturns { + if counter == 0 { + return MethodReturns::SelfCall(0); + } + mozak_sdk::call_send( + self_id, + MethodArgs::SelfCall(self_id, counter - 1), + dispatch, + ); + + MethodReturns::SelfCall(counter) +} diff --git a/examples/selfcaller/main_mozak.rs b/examples/selfcaller/main_mozak.rs new file mode 100644 index 000000000..7347e8ebd --- /dev/null +++ b/examples/selfcaller/main_mozak.rs @@ -0,0 +1,17 @@ +#![no_main] +#![allow(unused_attributes)] +#![feature(restricted_std)] + +mod core_logic; + +use core_logic::{dispatch, MethodArgs, MethodReturns}; +use mozak_sdk::call_receive; + +pub fn main() { + while let Some((_caller, argument, return_)) = call_receive::() { + assert!(dispatch(argument) == return_); + } +} + +// We define `main()` to be the program's entry point. +mozak_sdk::entry!(main); diff --git a/examples/selfcaller/main_native.rs b/examples/selfcaller/main_native.rs new file mode 100644 index 000000000..9c19cff52 --- /dev/null +++ b/examples/selfcaller/main_native.rs @@ -0,0 +1,20 @@ +#![feature(restricted_std)] +#![allow(unused_attributes)] + +mod core_logic; + +use mozak_sdk::common::types::ProgramIdentifier; + +use crate::core_logic::{dispatch, MethodArgs}; + +fn main() { + let self_caller_program = ProgramIdentifier::new_from_rand_seed(5); + + mozak_sdk::call_send( + self_caller_program, + MethodArgs::SelfCall(self_caller_program, 5), + dispatch, + ); + + mozak_sdk::native::dump_proving_files("selfcaller", self_caller_program); +} diff --git a/sdk/src/common/system.rs b/sdk/src/common/system.rs index 94b42611a..e9719078b 100644 --- a/sdk/src/common/system.rs +++ b/sdk/src/common/system.rs @@ -11,6 +11,8 @@ use super::types::{ CallTapeType, EventTapeType, PrivateInputTapeType, PublicInputTapeType, SystemTape, }; #[cfg(target_os = "mozakvm")] +use super::types::{SelfCallExtendedProgramIdentifier, SelfCallExtensionFlag}; +#[cfg(target_os = "mozakvm")] use crate::common::types::{CanonicalOrderedTemporalHints, CrossProgramCall, ProgramIdentifier}; #[cfg(target_os = "mozakvm")] use crate::mozakvm::helpers::{ @@ -67,7 +69,10 @@ pub(crate) static mut SYSTEM_TAPE: Lazy = Lazy::new(|| { private_input_tape: PrivateInputTapeType::default(), public_input_tape: PublicInputTapeType::default(), call_tape: CallTapeType { - self_prog_id: get_self_prog_id(), + extended_self_prog_id: SelfCallExtendedProgramIdentifier( + get_self_prog_id(), + SelfCallExtensionFlag::default(), + ), cast_list: get_rkyv_deserialized!(Vec, _mozak_cast_list), reader: Some(get_rkyv_archived!(Vec, _mozak_call_tape)), index: 0, diff --git a/sdk/src/common/traits.rs b/sdk/src/common/traits.rs index 3bc0c67d2..0df396931 100644 --- a/sdk/src/common/traits.rs +++ b/sdk/src/common/traits.rs @@ -4,6 +4,7 @@ use rkyv::ser::{AllocSerializer, Composite}; use rkyv::util::AlignedVec; use rkyv::{Archive, Deserialize, Serialize}; +use super::types::cross_program_call::SelfCallExtendedProgramIdentifier; use crate::common::types::{Event, ProgramIdentifier}; pub trait RkyvSerializable = rkyv::Serialize< @@ -14,9 +15,11 @@ pub trait CallReturn = ?Sized + Clone + Default + RkyvSerializable + Archive; /// A data struct that is aware of it's own ID pub trait SelfIdentify { - fn get_self_identity(&self) -> ProgramIdentifier; + fn get_self_identity(&self) -> SelfCallExtendedProgramIdentifier { + SelfCallExtendedProgramIdentifier::default() + } #[allow(dead_code)] - fn set_self_identity(&mut self, id: ProgramIdentifier); + fn set_self_identity(&mut self, _id: SelfCallExtendedProgramIdentifier) {} } /// `Call` trait provides methods `send` & `receive` to use an diff --git a/sdk/src/common/types/cross_program_call.rs b/sdk/src/common/types/cross_program_call.rs index 5c68d1340..effa60272 100644 --- a/sdk/src/common/types/cross_program_call.rs +++ b/sdk/src/common/types/cross_program_call.rs @@ -1,3 +1,56 @@ +use super::ProgramIdentifier; + +#[derive( + Default, + Copy, + Clone, + Hash, + Eq, + PartialEq, + Ord, + PartialOrd, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[cfg_attr( + not(target_os = "mozakvm"), + derive(Debug, serde::Serialize, serde::Deserialize) +)] +/// `SelfCallExtension` is a boolean value that differentiates the +/// two program instances when a program calls itself under CPC. For +/// example, if a program `P` in some function `f` wants to call another +/// function `f'` in `P` under CPC regime, the caller and callee may form +/// tuple as: `((P, 0), (P, 1))` or `((P, 1), (P, 0))`. The added digits +/// help separate the two instances of call and hold no numeric significance +/// apart from mere differentiators. +pub struct SelfCallExtensionFlag(pub u8); + +impl SelfCallExtensionFlag { + /// Provides a flag different from given flag. In essence, if `0` is + /// provided, `1` is returned and vice versa + #[must_use] + pub fn differentiate_from(flag: Self) -> Self { Self(1 - flag.0) } +} + +#[derive( + Default, + Clone, + Hash, + Eq, + PartialEq, + Ord, + PartialOrd, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[cfg_attr( + not(target_os = "mozakvm"), + derive(Debug, serde::Serialize, serde::Deserialize) +)] +pub struct SelfCallExtendedProgramIdentifier(pub ProgramIdentifier, pub SelfCallExtensionFlag); + #[derive( Default, Clone, Hash, PartialEq, PartialOrd, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, )] @@ -7,8 +60,8 @@ )] #[allow(clippy::pub_underscore_fields)] pub struct CrossProgramCall { - pub caller: super::ProgramIdentifier, - pub callee: super::ProgramIdentifier, + pub caller: SelfCallExtendedProgramIdentifier, + pub callee: SelfCallExtendedProgramIdentifier, pub argument: super::RawMessage, pub return_: super::RawMessage, } diff --git a/sdk/src/common/types/mod.rs b/sdk/src/common/types/mod.rs index 9c5b0b8fe..48f4193d0 100644 --- a/sdk/src/common/types/mod.rs +++ b/sdk/src/common/types/mod.rs @@ -7,7 +7,9 @@ pub(crate) mod state_address; pub(crate) mod state_object; pub(crate) mod system_tape; -pub use cross_program_call::CrossProgramCall; +pub use cross_program_call::{ + CrossProgramCall, SelfCallExtendedProgramIdentifier, SelfCallExtensionFlag, +}; pub use event::{CanonicalEvent, CanonicalOrderedTemporalHints, Event, EventType}; pub use poseidon2hash::Poseidon2Hash; pub use program_identifier::ProgramIdentifier; diff --git a/sdk/src/mozakvm/calltape.rs b/sdk/src/mozakvm/calltape.rs index 5acfc5fb2..490b460e2 100644 --- a/sdk/src/mozakvm/calltape.rs +++ b/sdk/src/mozakvm/calltape.rs @@ -2,13 +2,15 @@ use rkyv::rancor::{Panic, Strategy}; use rkyv::{Archive, Deserialize}; use crate::common::traits::{Call, CallArgument, CallReturn, SelfIdentify}; -use crate::common::types::{CrossProgramCall, ProgramIdentifier}; +use crate::common::types::{ + CrossProgramCall, ProgramIdentifier, SelfCallExtendedProgramIdentifier, SelfCallExtensionFlag, +}; /// Represents the `CallTape` under `mozak-vm` #[derive(Default, Clone)] pub struct CallTape { pub(crate) cast_list: Vec, - pub(crate) self_prog_id: ProgramIdentifier, + pub(crate) extended_self_prog_id: SelfCallExtendedProgramIdentifier, pub(crate) reader: Option<&'static as Archive>::Archived>, pub(crate) index: usize, } @@ -21,9 +23,9 @@ impl CallTape { } impl SelfIdentify for CallTape { - fn set_self_identity(&mut self, id: ProgramIdentifier) { self.self_prog_id = id; } - - fn get_self_identity(&self) -> ProgramIdentifier { self.self_prog_id } + fn get_self_identity(&self) -> SelfCallExtendedProgramIdentifier { + self.extended_self_prog_id.clone() + } } impl Call for CallTape { @@ -48,10 +50,14 @@ impl Call for CallTape { .unwrap(); // Ensure fields are correctly populated for caller and callee - assert!(cpcmsg.caller == self.get_self_identity()); - assert!(cpcmsg.callee == recipient_program); + assert!(cpcmsg.caller.0 == self.get_self_identity().0); + assert!(cpcmsg.callee.0 == recipient_program); assert!(self.is_casted_actor(&recipient_program)); + if self.get_self_identity().0 == recipient_program { + assert!(cpcmsg.callee.1 == SelfCallExtensionFlag::differentiate_from(cpcmsg.caller.1)); + } + // Deserialize the `arguments` seen on the tape, and assert let zcd_args = unsafe { rkyv::access_unchecked::(&cpcmsg.argument.0[..]) }; let deserialized_args = @@ -85,7 +91,17 @@ impl Call for CallTape { ::Archived: Deserialize>, { // Loop until we completely traverse the call tape in the // worst case. Hopefully, we see a message directed towards us - // before the end + // before the end. + + // SELF CALL EXTENSION: Looping to be done twice, once for + // `(extended_self_prog_id, 0)` and once for `(extended_self_prog_id, 1)` + let current_traversal_round: u8 = self.extended_self_prog_id.1 .0; + if self.index >= self.reader.unwrap().len() && current_traversal_round == 0 { + self.index = 0; + self.extended_self_prog_id.1 = + SelfCallExtensionFlag::differentiate_from(self.extended_self_prog_id.1); + } + while self.index < self.reader.unwrap().len() { // Get the "archived" version of the message, where we will // pick and choose what we will deserialize @@ -97,23 +113,25 @@ impl Call for CallTape { // Well, once we are sure that we were not the caller, we can // either be a callee in which case we process and send information // back or we continue searching. - let callee: ProgramIdentifier = zcd_cpcmsg + let callee: SelfCallExtendedProgramIdentifier = zcd_cpcmsg .callee .deserialize(Strategy::<_, Panic>::wrap(&mut ())) .unwrap(); - if self.self_prog_id == callee { - // First, ensure that we are not the caller, no-one can call - // themselves. (Even if they can w.r.t. self-calling extension, - // the `caller` field would remain distinct) - let caller: ProgramIdentifier = zcd_cpcmsg + if callee == self.extended_self_prog_id { + // Under self call extensions, a caller can call themselves, given + // the `SelfCallExtensionFlag` is different between them + let caller: SelfCallExtendedProgramIdentifier = zcd_cpcmsg .caller .deserialize(Strategy::<_, Panic>::wrap(&mut ())) .unwrap(); - assert!(caller != self.self_prog_id); + + if caller.0 == callee.0 { + assert!(caller.1 == SelfCallExtensionFlag::differentiate_from(callee.1)); + } // Before accepting, make sure that caller was a part of castlist - assert!(self.is_casted_actor(&caller)); + assert!(self.is_casted_actor(&caller.0)); let archived_args = unsafe { rkyv::access_unchecked::(zcd_cpcmsg.argument.0.as_slice()) }; @@ -123,7 +141,7 @@ impl Call for CallTape { unsafe { rkyv::access_unchecked::(zcd_cpcmsg.return_.0.as_slice()) }; let ret: R = archived_ret.deserialize(Strategy::wrap(&mut ())).unwrap(); - return Some((caller, args, ret)); + return Some((caller.0, args, ret)); } } None diff --git a/sdk/src/mozakvm/eventtape.rs b/sdk/src/mozakvm/eventtape.rs index cc0addd40..e5aef7084 100644 --- a/sdk/src/mozakvm/eventtape.rs +++ b/sdk/src/mozakvm/eventtape.rs @@ -4,6 +4,7 @@ use rkyv::{Archive, Deserialize}; use crate::common::traits::{EventEmit, SelfIdentify}; use crate::common::types::{ CanonicalEvent, CanonicalOrderedTemporalHints, Event, ProgramIdentifier, + SelfCallExtendedProgramIdentifier, SelfCallExtensionFlag, }; /// Represents the `EventTape` under native execution @@ -16,9 +17,16 @@ pub struct EventTape { } impl SelfIdentify for EventTape { - fn set_self_identity(&mut self, id: ProgramIdentifier) { self.self_prog_id = id } + fn set_self_identity(&mut self, id: SelfCallExtendedProgramIdentifier) { + self.self_prog_id = id.0; + } - fn get_self_identity(&self) -> ProgramIdentifier { self.self_prog_id } + // WARNING: returns from this function does not provide + // the correct `SelfCallExtensionFlag` simply because event + // tape doesn't need it for anything. + fn get_self_identity(&self) -> SelfCallExtendedProgramIdentifier { + SelfCallExtendedProgramIdentifier(self.self_prog_id, SelfCallExtensionFlag::default()) + } } impl EventEmit for EventTape { diff --git a/sdk/src/native/calltape.rs b/sdk/src/native/calltape.rs index cf145e4cc..b8883c929 100644 --- a/sdk/src/native/calltape.rs +++ b/sdk/src/native/calltape.rs @@ -5,7 +5,10 @@ use rkyv::rancor::{Panic, Strategy}; use rkyv::Deserialize; use crate::common::traits::{Call, CallArgument, CallReturn, SelfIdentify}; -use crate::common::types::{CrossProgramCall, ProgramIdentifier, RawMessage}; +use crate::common::types::{ + CrossProgramCall, ProgramIdentifier, RawMessage, SelfCallExtendedProgramIdentifier, + SelfCallExtensionFlag, +}; use crate::native::helpers::IdentityStack; /// Represents the `CallTape` under native execution @@ -22,14 +25,17 @@ impl std::fmt::Debug for CallTape { } impl SelfIdentify for CallTape { - fn set_self_identity(&mut self, id: ProgramIdentifier) { + fn set_self_identity(&mut self, id: SelfCallExtendedProgramIdentifier) { self.identity_stack.borrow_mut().add_identity(id); } - fn get_self_identity(&self) -> ProgramIdentifier { self.identity_stack.borrow().top_identity() } + fn get_self_identity(&self) -> SelfCallExtendedProgramIdentifier { + self.identity_stack.borrow().top_identity() + } } impl Call for CallTape { + #[allow(clippy::similar_names)] fn send( &mut self, recipient_program: ProgramIdentifier, @@ -41,12 +47,20 @@ impl Call for CallTape { R: CallReturn, ::Archived: Deserialize>, ::Archived: Deserialize>, { + let caller = self.get_self_identity(); + let mut callee = + SelfCallExtendedProgramIdentifier(recipient_program, SelfCallExtensionFlag::default()); + if callee.0 == caller.0 { + callee.1 = SelfCallExtensionFlag::differentiate_from(caller.1); + } + let unresolved_return_value = RawMessage::default(); + // Create a skeletal `CrossProgramCall` to be resolved via "resolver" let msg = CrossProgramCall { - caller: self.get_self_identity(), - callee: recipient_program, + caller, + callee: callee.clone(), argument: rkyv::to_bytes::<_, 256, _>(&argument).unwrap().into(), - return_: RawMessage::default(), // Unfilled: we have to still resolve it + return_: unresolved_return_value, }; // Remember where in the "writer" are we pushing this. @@ -58,7 +72,7 @@ impl Call for CallTape { self.writer.push(msg); // resolve the return value and add to where message was - self.set_self_identity(recipient_program); + self.set_self_identity(callee); let resolved_value = resolver(argument); self.writer[inserted_idx].return_ = rkyv::to_bytes::<_, 256, _>(&resolved_value).unwrap().into(); @@ -81,11 +95,11 @@ impl Call for CallTape { mod tests { use super::CallTape; use crate::common::traits::Call; - use crate::common::types::ProgramIdentifier; + use crate::common::types::cross_program_call::SelfCallExtendedProgramIdentifier; - fn test_pid_generator(val: u8) -> ProgramIdentifier { - let mut pid = ProgramIdentifier::default(); - pid.0 .0[0] = val; + fn test_pid_generator(val: u8) -> SelfCallExtendedProgramIdentifier { + let mut pid = SelfCallExtendedProgramIdentifier::default(); + pid.0 .0 .0[0] = val; pid } @@ -98,10 +112,13 @@ mod tests { let resolver = |val: A| -> B { B::from(val + 1) }; - let response = calltape.send(test_pid_generator(1), 1 as A, resolver); + let response = calltape.send(test_pid_generator(1).0, 1 as A, resolver); assert_eq!(response, 2); assert_eq!(calltape.writer.len(), 1); - assert_eq!(calltape.writer[0].caller, ProgramIdentifier::default()); + assert_eq!( + calltape.writer[0].caller, + SelfCallExtendedProgramIdentifier::default() + ); assert_eq!(calltape.writer[0].callee, test_pid_generator(1)); } } diff --git a/sdk/src/native/eventtape.rs b/sdk/src/native/eventtape.rs index ecb49b147..bf468477f 100644 --- a/sdk/src/native/eventtape.rs +++ b/sdk/src/native/eventtape.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use std::rc::Rc; use crate::common::traits::{EventEmit, SelfIdentify}; +use crate::common::types::cross_program_call::SelfCallExtendedProgramIdentifier; use crate::common::types::{ CanonicalEvent, CanonicalOrderedTemporalHints, Event, ProgramIdentifier, }; @@ -124,14 +125,16 @@ impl std::fmt::Debug for EventTape { } impl SelfIdentify for EventTape { - fn set_self_identity(&mut self, _id: ProgramIdentifier) { unimplemented!() } + fn set_self_identity(&mut self, _id: SelfCallExtendedProgramIdentifier) { unimplemented!() } - fn get_self_identity(&self) -> ProgramIdentifier { self.identity_stack.borrow().top_identity() } + fn get_self_identity(&self) -> SelfCallExtendedProgramIdentifier { + self.identity_stack.borrow().top_identity() + } } impl EventEmit for EventTape { fn emit(&mut self, event: Event) { - let self_id = self.get_self_identity(); + let self_id = self.get_self_identity().0; assert_ne!(self_id, ProgramIdentifier::default()); self.writer diff --git a/sdk/src/native/helpers.rs b/sdk/src/native/helpers.rs index 16a78a24a..d40abc21e 100644 --- a/sdk/src/native/helpers.rs +++ b/sdk/src/native/helpers.rs @@ -7,17 +7,20 @@ use plonky2::field::types::Field; use plonky2::hash::poseidon2::Poseidon2Hash as Plonky2Poseidon2Hash; use plonky2::plonk::config::{GenericHashOut, Hasher}; +use crate::common::types::cross_program_call::SelfCallExtendedProgramIdentifier; use crate::common::types::poseidon2hash::RATE; use crate::common::types::{Poseidon2Hash, ProgramIdentifier}; /// Represents a stack for call contexts during native execution. #[derive(Default, Clone, Debug, serde::Serialize, serde::Deserialize)] -pub struct IdentityStack(Vec); +pub struct IdentityStack(Vec); impl IdentityStack { - pub fn add_identity(&mut self, id: ProgramIdentifier) { self.0.push(id); } + pub fn add_identity(&mut self, id: SelfCallExtendedProgramIdentifier) { self.0.push(id); } - pub fn top_identity(&self) -> ProgramIdentifier { self.0.last().copied().unwrap_or_default() } + pub fn top_identity(&self) -> SelfCallExtendedProgramIdentifier { + self.0.last().cloned().unwrap_or_default() + } pub fn rm_identity(&mut self) { self.0.truncate(self.0.len().saturating_sub(1)); } } @@ -41,13 +44,13 @@ pub(crate) struct Bin { path: String, } -/// Manually add a `ProgramIdentifier` onto `IdentityStack`. Useful -/// when one want to escape automatic management of `IdentityStack` +/// Manually add a `SelfCallExtendedProgramIdentifier` onto `IdentityStack`. +/// Useful when one want to escape automatic management of `IdentityStack` /// via cross-program-calls sends (ideally temporarily). /// CAUTION: Manual function for `IdentityStack`, misuse may lead /// to system tape generation failure. #[cfg(all(feature = "std", not(target_os = "mozakvm")))] -pub fn add_identity(id: crate::common::types::ProgramIdentifier) { +pub fn add_identity(id: SelfCallExtendedProgramIdentifier) { unsafe { crate::common::system::SYSTEM_TAPE .call_tape @@ -57,7 +60,7 @@ pub fn add_identity(id: crate::common::types::ProgramIdentifier) { } } -/// Manually remove a `ProgramIdentifier` from `IdentityStack`. +/// Manually remove a `SelfCallExtendedProgramIdentifier` from `IdentityStack`. /// Useful when one want to escape automatic management of `IdentityStack` /// via cross-program-calls sends (ideally temporarily). /// CAUTION: Manual function for `IdentityStack`, misuse may lead diff --git a/sdk/src/native/inputtape.rs b/sdk/src/native/inputtape.rs index 2e5cb93a1..b7a41e1df 100644 --- a/sdk/src/native/inputtape.rs +++ b/sdk/src/native/inputtape.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use std::rc::Rc; use crate::common::traits::SelfIdentify; +use crate::common::types::cross_program_call::SelfCallExtendedProgramIdentifier; use crate::common::types::{ProgramIdentifier, RawMessage}; use crate::native::helpers::IdentityStack; @@ -20,11 +21,13 @@ impl std::fmt::Debug for RawTape { } impl SelfIdentify for RawTape { - fn set_self_identity(&mut self, id: ProgramIdentifier) { + fn set_self_identity(&mut self, id: SelfCallExtendedProgramIdentifier) { self.identity_stack.borrow_mut().add_identity(id); } - fn get_self_identity(&self) -> ProgramIdentifier { self.identity_stack.borrow().top_identity() } + fn get_self_identity(&self) -> SelfCallExtendedProgramIdentifier { + self.identity_stack.borrow().top_identity() + } } /// We have to implement `std::io::Write` in native context @@ -33,7 +36,7 @@ impl SelfIdentify for RawTape { /// `stdread` or any other feature flag. impl std::io::Write for RawTape { fn write(&mut self, buf: &[u8]) -> Result { - let self_id = self.get_self_identity(); + let self_id = self.get_self_identity().0; assert_ne!(self_id, ProgramIdentifier::default()); self.writer.entry(self_id).or_default().0.extend(buf);