Skip to content

Commit

Permalink
wip type parameter to send
Browse files Browse the repository at this point in the history
  • Loading branch information
anorth committed May 29, 2023
1 parent f4f3f34 commit 735a115
Show file tree
Hide file tree
Showing 5 changed files with 385 additions and 290 deletions.
200 changes: 132 additions & 68 deletions fvm/src/kernel/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,70 @@ where
fn machine(&self) -> &<Self::CallManager as CallManager>::Machine {
self.call_manager.machine()
}

fn send<K: Kernel<CallManager = C>>(
&mut self,
recipient: &Address,
method: MethodNum,
params_id: BlockId,
value: &TokenAmount,
gas_limit: Option<Gas>,
flags: SendFlags,
) -> Result<SendResult> {
let from = self.actor_id;
let read_only = self.read_only || flags.read_only();

if read_only && !value.is_zero() {
return Err(syscall_error!(ReadOnly; "cannot transfer value when read-only").into());
}

// Load parameters.
let params = if params_id == NO_DATA_BLOCK_ID {
None
} else {
Some(self.blocks.get(params_id)?.clone())
};

// Make sure we can actually store the return block.
if self.blocks.is_full() {
return Err(syscall_error!(LimitExceeded; "cannot store return block").into());
}

// Send.
let result = self.call_manager.with_transaction(|cm| {
cm.send::<K>(
from, *recipient, method, params, value, gas_limit, read_only,
)
})?;

// Store result and return.
Ok(match result {
InvocationResult {
exit_code,
value: Some(blk),
} => {
let block_stat = blk.stat();
let block_id = self
.blocks
.put(blk)
.or_fatal()
.context("failed to store a valid return value")?;
SendResult {
block_id,
block_stat,
exit_code,
}
}
InvocationResult {
exit_code,
value: None,
} => SendResult {
block_id: NO_DATA_BLOCK_ID,
block_stat: BlockStat { codec: 0, size: 0 },
exit_code,
},
})
}
}

impl<C> DefaultKernel<C>
Expand Down Expand Up @@ -358,74 +422,74 @@ where
}
}

impl<C> SendOps for DefaultKernel<C>
where
C: CallManager,
{
fn send(
&mut self,
recipient: &Address,
method: MethodNum,
params_id: BlockId,
value: &TokenAmount,
gas_limit: Option<Gas>,
flags: SendFlags,
) -> Result<SendResult> {
let from = self.actor_id;
let read_only = self.read_only || flags.read_only();

if read_only && !value.is_zero() {
return Err(syscall_error!(ReadOnly; "cannot transfer value when read-only").into());
}

// Load parameters.
let params = if params_id == NO_DATA_BLOCK_ID {
None
} else {
Some(self.blocks.get(params_id)?.clone())
};

// Make sure we can actually store the return block.
if self.blocks.is_full() {
return Err(syscall_error!(LimitExceeded; "cannot store return block").into());
}

// Send.
let result = self.call_manager.with_transaction(|cm| {
cm.send::<Self>(
from, *recipient, method, params, value, gas_limit, read_only,
)
})?;

// Store result and return.
Ok(match result {
InvocationResult {
exit_code,
value: Some(blk),
} => {
let block_stat = blk.stat();
let block_id = self
.blocks
.put(blk)
.or_fatal()
.context("failed to store a valid return value")?;
SendResult {
block_id,
block_stat,
exit_code,
}
}
InvocationResult {
exit_code,
value: None,
} => SendResult {
block_id: NO_DATA_BLOCK_ID,
block_stat: BlockStat { codec: 0, size: 0 },
exit_code,
},
})
}
}
// impl<C> SendOps for DefaultKernel<C>
// where
// C: CallManager,
// {
// fn send<K: Kernel<CallManager = C>>(
// &mut self,
// recipient: &Address,
// method: MethodNum,
// params_id: BlockId,
// value: &TokenAmount,
// gas_limit: Option<Gas>,
// flags: SendFlags,
// ) -> Result<SendResult> {
// let from = self.actor_id;
// let read_only = self.read_only || flags.read_only();
//
// if read_only && !value.is_zero() {
// return Err(syscall_error!(ReadOnly; "cannot transfer value when read-only").into());
// }
//
// // Load parameters.
// let params = if params_id == NO_DATA_BLOCK_ID {
// None
// } else {
// Some(self.blocks.get(params_id)?.clone())
// };
//
// // Make sure we can actually store the return block.
// if self.blocks.is_full() {
// return Err(syscall_error!(LimitExceeded; "cannot store return block").into());
// }
//
// // Send.
// let result = self.call_manager.with_transaction(|cm| {
// cm.send::<K>(
// from, *recipient, method, params, value, gas_limit, read_only,
// )
// })?;
//
// // Store result and return.
// Ok(match result {
// InvocationResult {
// exit_code,
// value: Some(blk),
// } => {
// let block_stat = blk.stat();
// let block_id = self
// .blocks
// .put(blk)
// .or_fatal()
// .context("failed to store a valid return value")?;
// SendResult {
// block_id,
// block_stat,
// exit_code,
// }
// }
// InvocationResult {
// exit_code,
// value: None,
// } => SendResult {
// block_id: NO_DATA_BLOCK_ID,
// block_stat: BlockStat { codec: 0, size: 0 },
// exit_code,
// },
// })
// }
// }

impl<C> CircSupplyOps for DefaultKernel<C>
where
Expand Down
12 changes: 11 additions & 1 deletion fvm/src/kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub trait Kernel:
+ NetworkOps
+ RandomnessOps
+ SelfOps
+ SendOps
// + SendOps
+ LimiterOps
+ 'static
{
Expand Down Expand Up @@ -97,6 +97,16 @@ pub trait Kernel:

/// The kernel's underlying "machine".
fn machine(&self) -> &<Self::CallManager as CallManager>::Machine;

fn send<K: Kernel<CallManager = Self::CallManager>>(
&mut self,
recipient: &Address,
method: u64,
params: BlockId,
value: &TokenAmount,
gas_limit: Option<Gas>,
flags: SendFlags,
) -> Result<SendResult>;
}

/// Network-related operations.
Expand Down
6 changes: 3 additions & 3 deletions fvm/src/syscalls/send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use crate::Kernel;
/// Send a message to another actor. The result is placed as a CBOR-encoded
/// receipt in the block registry, and can be retrieved by the returned BlockId.
#[allow(clippy::too_many_arguments)]
pub fn send(
context: Context<'_, impl Kernel>,
pub fn send<K: Kernel>(
context: Context<'_, K>,
recipient_off: u32,
recipient_len: u32,
method: u64,
Expand Down Expand Up @@ -43,7 +43,7 @@ pub fn send(
exit_code,
} = context
.kernel
.send(&recipient, method, params_id, &value, gas_limit, flags)?;
.send::<K>(&recipient, method, params_id, &value, gas_limit, flags)?;

Ok(sys::out::send::Send {
exit_code: exit_code.value(),
Expand Down
4 changes: 3 additions & 1 deletion testing/conformance/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ use lazy_static::lazy_static;
use libipld_core::ipld::Ipld;
use regex::Regex;
use walkdir::DirEntry;
use fvm::call_manager::DefaultCallManager;
use fvm::DefaultKernel;

use crate::tracing::TestTraceFun;
use crate::vector::{MessageVector, Variant};
Expand Down Expand Up @@ -238,7 +240,7 @@ pub fn run_variant(
)
.unwrap();

let mut exec: DefaultExecutor<TestKernel> = DefaultExecutor::new(engine, machine)?;
let mut exec: DefaultExecutor<TestKernel<DefaultKernel<DefaultCallManager<TestMachine>>>> = DefaultExecutor::new(engine, machine)?;
let mut rets = Vec::new();

// Apply all messages in the vector.
Expand Down
Loading

0 comments on commit 735a115

Please sign in to comment.