Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade for new spawn #86

Merged
merged 2 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions contracts/spawn-callee/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ use ckb_std::syscalls;
use core::result::Result;

pub fn main() -> Result<(), Error> {
assert_eq!(syscalls::get_memory_limit(), 8);
let argv = ckb_std::env::argv();
ckb_std::debug!("argv: {:?}", argv);
let mut std_fds: [u64; 2] = [0; 2];
syscalls::inherited_file_descriptors(&mut std_fds);
let mut out = vec![];
for arg in argv {
out.extend_from_slice(arg.to_bytes());
}
syscalls::set_content(&out)?;
let len = syscalls::write(std_fds[1], &out)?;
assert_eq!(len, 10);
Ok(())
}
16 changes: 10 additions & 6 deletions contracts/spawn-callee/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ pub enum Error {
ItemMissing,
LengthNotEnough,
Encoding,
SpawnExceededMaxContentLength,
SpawnWrongMemoryLimit,
SpawnExceededMaxPeakMemory,
WaitFailure,
InvalidFd,
OtherEndClosed,
MaxVmsSpawned,
MaxFdsCreated,
}

impl From<SysError> for Error {
Expand All @@ -20,9 +22,11 @@ impl From<SysError> for Error {
ItemMissing => Self::ItemMissing,
LengthNotEnough(_) => Self::LengthNotEnough,
Encoding => Self::Encoding,
SpawnExceededMaxContentLength => Self::SpawnExceededMaxContentLength,
SpawnWrongMemoryLimit => Self::SpawnWrongMemoryLimit,
SpawnExceededMaxPeakMemory => Self::SpawnExceededMaxPeakMemory,
WaitFailure => Self::WaitFailure,
InvalidFd => Self::InvalidFd,
OtherEndClosed => Self::OtherEndClosed,
MaxVmsSpawned => Self::MaxVmsSpawned,
MaxFdsCreated => Self::MaxFdsCreated,
Unknown(err_code) => panic!("unexpected sys error {}", err_code),
}
}
Expand Down
39 changes: 22 additions & 17 deletions contracts/spawn-caller-by-code-hash/src/entry.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
// Import from `core` instead of from `std` since we are in no-std mode
use crate::error::Error;
use alloc::vec;
use ckb_std::ckb_constants::Source;
use ckb_std::ckb_types::core::ScriptHashType;
use ckb_std::high_level::{load_script, spawn_cell};
use ckb_std::syscalls;
use core::ffi::CStr;
use core::result::Result;

pub fn main() -> Result<(), Error> {
let arg1 = CStr::from_bytes_with_nul(b"hello\0").unwrap();
let arg2 = CStr::from_bytes_with_nul(b"world\0").unwrap();
let argv = [
CStr::from_bytes_with_nul(b"hello\0").unwrap(),
CStr::from_bytes_with_nul(b"world\0").unwrap(),
];
let mut std_fds: [u64; 2] = [0, 0];
let mut son_fds: [u64; 3] = [0, 0, 0];
let (r0, w0) = syscalls::pipe()?;
std_fds[0] = r0;
son_fds[1] = w0;
let (r1, w1) = syscalls::pipe()?;
std_fds[1] = w1;
son_fds[0] = r1;
let code_hash = load_script().unwrap().args().raw_data();
ckb_std::debug!("code_hash: {:?}", code_hash);

let mut content = vec![0; 80];
let ret = spawn_cell(
&code_hash[..],
ScriptHashType::Data1,
&[arg1, arg2][..],
8,
&mut content,
spawn_cell(&code_hash[..], ScriptHashType::Data1, &argv, &son_fds)?;
let mut buf: [u8; 256] = [0; 256];
let len = syscalls::read(std_fds[0], &mut buf)?;
assert_eq!(len, 10);
buf[len] = 0;
assert_eq!(
CStr::from_bytes_until_nul(&buf).unwrap().to_str().unwrap(),
"helloworld"
);
assert!(ret == Ok(0));
assert!(content.len() == 10);
content.resize(content.len() + 1, 0);
let c_str = CStr::from_bytes_until_nul(&content).unwrap();
assert_eq!(c_str.to_str().unwrap(), "helloworld");
Ok(())
}
16 changes: 10 additions & 6 deletions contracts/spawn-caller-by-code-hash/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ pub enum Error {
ItemMissing,
LengthNotEnough,
Encoding,
SpawnExceededMaxContentLength,
SpawnWrongMemoryLimit,
SpawnExceededMaxPeakMemory,
WaitFailure,
InvalidFd,
OtherEndClosed,
MaxVmsSpawned,
MaxFdsCreated,
}

impl From<SysError> for Error {
Expand All @@ -20,9 +22,11 @@ impl From<SysError> for Error {
ItemMissing => Self::ItemMissing,
LengthNotEnough(_) => Self::LengthNotEnough,
Encoding => Self::Encoding,
SpawnExceededMaxContentLength => Self::SpawnExceededMaxContentLength,
SpawnWrongMemoryLimit => Self::SpawnWrongMemoryLimit,
SpawnExceededMaxPeakMemory => Self::SpawnExceededMaxPeakMemory,
WaitFailure => Self::WaitFailure,
InvalidFd => Self::InvalidFd,
OtherEndClosed => Self::OtherEndClosed,
MaxVmsSpawned => Self::MaxVmsSpawned,
MaxFdsCreated => Self::MaxFdsCreated,
Unknown(err_code) => panic!("unexpected sys error {}", err_code),
}
}
Expand Down
46 changes: 30 additions & 16 deletions contracts/spawn-caller/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,36 @@ use core::ffi::CStr;
use core::result::Result;

pub fn main() -> Result<(), Error> {
let arg1 = CStr::from_bytes_with_nul(b"hello\0").unwrap();
let arg2 = CStr::from_bytes_with_nul(b"world\0").unwrap();

let mut spgs_exit_code: i8 = 0;
let mut spgs_content = [0u8; 80];
let mut spgs_content_length: u64 = 80;
let spgs = syscalls::SpawnArgs {
memory_limit: 8,
exit_code: &mut spgs_exit_code as *mut i8,
content: &mut spgs_content as *mut u8,
content_length: &mut spgs_content_length as *mut u64,
let argc: u64 = 2;
let argv = {
let mut argv = alloc::vec![core::ptr::null(); argc as usize + 1];
argv[0] = CStr::from_bytes_with_nul(b"hello\0").unwrap().as_ptr();
argv[1] = CStr::from_bytes_with_nul(b"world\0").unwrap().as_ptr();
argv
};
let mut std_fds: [u64; 2] = [0, 0];
let mut son_fds: [u64; 3] = [0, 0, 0];
let (r0, w0) = syscalls::pipe()?;
std_fds[0] = r0;
son_fds[1] = w0;
let (r1, w1) = syscalls::pipe()?;
std_fds[1] = w1;
son_fds[0] = r1;
let mut pid: u64 = 0;
let mut spgs = syscalls::SpawnArgs {
argc: argc,
argv: argv.as_ptr(),
process_id: &mut pid as *mut u64,
inherited_fds: son_fds.as_ptr(),
};
let ret = syscalls::spawn(1, Source::CellDep, 0, &[arg1, arg2][..], &spgs);
assert!(ret == 0);
assert!(spgs_exit_code == 0);
let c_str = CStr::from_bytes_until_nul(&spgs_content).unwrap();
assert_eq!(c_str.to_str().unwrap(), "helloworld");
syscalls::spawn(1, Source::CellDep, 0, 0, &mut spgs)?;
let mut buf: [u8; 256] = [0; 256];
let len = syscalls::read(std_fds[0], &mut buf)?;
assert_eq!(len, 10);
buf[len] = 0;
assert_eq!(
CStr::from_bytes_until_nul(&buf).unwrap().to_str().unwrap(),
"helloworld"
);
Ok(())
}
16 changes: 10 additions & 6 deletions contracts/spawn-caller/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ pub enum Error {
ItemMissing,
LengthNotEnough,
Encoding,
SpawnExceededMaxContentLength,
SpawnWrongMemoryLimit,
SpawnExceededMaxPeakMemory,
WaitFailure,
InvalidFd,
OtherEndClosed,
MaxVmsSpawned,
MaxFdsCreated,
}

impl From<SysError> for Error {
Expand All @@ -20,9 +22,11 @@ impl From<SysError> for Error {
ItemMissing => Self::ItemMissing,
LengthNotEnough(_) => Self::LengthNotEnough,
Encoding => Self::Encoding,
SpawnExceededMaxContentLength => Self::SpawnExceededMaxContentLength,
SpawnWrongMemoryLimit => Self::SpawnWrongMemoryLimit,
SpawnExceededMaxPeakMemory => Self::SpawnExceededMaxPeakMemory,
WaitFailure => Self::WaitFailure,
InvalidFd => Self::InvalidFd,
OtherEndClosed => Self::OtherEndClosed,
MaxVmsSpawned => Self::MaxVmsSpawned,
MaxFdsCreated => Self::MaxFdsCreated,
Unknown(err_code) => panic!("unexpected sys error {}", err_code),
}
}
Expand Down
18 changes: 13 additions & 5 deletions src/ckb_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,23 @@ pub const SYS_LOAD_CELL_DATA_AS_CODE: u64 = 2091;
pub const SYS_LOAD_CELL_DATA: u64 = 2092;
pub const SYS_DEBUG: u64 = 2177;
#[cfg(feature = "ckb2023")]
pub const SYS_SPAWN: u64 = 2101;
pub const SYS_SPAWN: u64 = 2601;
#[cfg(feature = "ckb2023")]
pub const SYS_GET_MEMORY_LIMIT: u64 = 2102;
pub const SYS_WAIT: u64 = 2602;
#[cfg(feature = "ckb2023")]
pub const SYS_SET_CONTENT: u64 = 2103;
pub const SYS_PROCESS_ID: u64 = 2603;
#[cfg(feature = "ckb2023")]
pub const SYS_LOAD_BLOCK_EXTENSION: u64 = 2104;
pub const SYS_PIPE: u64 = 2604;
#[cfg(feature = "ckb2023")]
pub const SYS_WRITE: u64 = 2605;
#[cfg(feature = "ckb2023")]
pub const SYS_READ: u64 = 2606;
#[cfg(feature = "ckb2023")]
pub const SYS_CURRENT_MEMORY: u64 = 2105;
pub const SYS_INHERITED_FD: u64 = 2607;
#[cfg(feature = "ckb2023")]
pub const SYS_CLOSE: u64 = 2608;
#[cfg(feature = "ckb2023")]
pub const SYS_LOAD_BLOCK_EXTENSION: u64 = 2104;

pub const CKB_SUCCESS: u64 = 0;
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
Expand Down
18 changes: 12 additions & 6 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,21 @@ pub enum SysError {
/// Data encoding error
Encoding,

/// Failed to wait. Its value is 5.
#[cfg(feature = "ckb2023")]
/// Content Length must be less than 256K.
SpawnExceededMaxContentLength,
WaitFailure,
/// Invalid file descriptor. Its value is 6.
#[cfg(feature = "ckb2023")]
/// MemoryLimit is between 1 and 8.
SpawnWrongMemoryLimit,
InvalidFd,
/// Reading from or writing to file descriptor failed due to other end closed. Its value is 7.
#[cfg(feature = "ckb2023")]
/// There is a maximum call depth limit by peak memory.
SpawnExceededMaxPeakMemory,
OtherEndClosed,
/// Max vms has been spawned. Its value is 8.
#[cfg(feature = "ckb2023")]
MaxVmsSpawned,
/// Max fds has been spawned. Its value is 9.
#[cfg(feature = "ckb2023")]
MaxFdsCreated,

/// Unknown syscall error number
Unknown(u64),
Expand Down
45 changes: 16 additions & 29 deletions src/high_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,40 +680,27 @@ pub fn exec_cell(
/// - CString::new("arg0").unwrap().as_c_str();
/// - if you want to pass a piece of bytes data, you may encode it to hexadecimal string or other format:
/// - high_level::encode_hex(&vec![0xff, 0xfe, 0xfd]);
/// * `memory_limit` - a number between 1 and 8.
/// - note each tick represents an additional 0.5M of memory.
/// * `content` - a buffer to saving the output by sub script.
/// - note the size of content will be shrinked after call.
/// * `inherited_fds` - the fd list to be passed to the child process.
#[cfg(feature = "ckb2023")]
pub fn spawn_cell(
code_hash: &[u8],
hash_type: ScriptHashType,
argv: &[&CStr],
memory_limit: u64,
content: &mut Vec<u8>,
) -> Result<i8, SysError> {
inherited_fds: &[u64],
) -> Result<u64, SysError> {
let index = look_for_dep_with_hash2(code_hash, hash_type)?;
let mut content_length = content.len() as u64;
let mut exit_code = 0i8;
let spgs = syscalls::SpawnArgs {
memory_limit,
exit_code: &mut exit_code as *mut i8,
content: content.as_mut_ptr(),
content_length: &mut content_length as *mut u64,
};
let ret = syscalls::spawn(index, Source::CellDep, 0, argv, &spgs);
match ret {
0 => {
content.truncate(content_length as usize);
Ok(exit_code)
}
1 => Err(SysError::IndexOutOfBound),
2 => Err(SysError::ItemMissing),
3 => Err(SysError::LengthNotEnough(content.len())),
4 => Err(SysError::Encoding),
5 => Err(SysError::SpawnExceededMaxContentLength),
6 => Err(SysError::SpawnWrongMemoryLimit),
7 => Err(SysError::SpawnExceededMaxPeakMemory),
r => Err(SysError::Unknown(r)),
let argc = argv.len();
let mut process_id: u64 = 0;
let mut argv_ptr = alloc::vec![core::ptr::null(); argc + 1];
for (idx, cstr) in argv.into_iter().enumerate() {
argv_ptr[idx] = cstr.as_ptr();
}
let mut spgs = syscalls::SpawnArgs {
argc: argc as u64,
argv: argv_ptr.as_ptr(),
process_id: &mut process_id as *mut u64,
inherited_fds: inherited_fds.as_ptr(),
};
syscalls::spawn(index, Source::CellDep, 0, 0, &mut spgs)?;
Ok(process_id)
}
Loading
Loading