Skip to content

Commit

Permalink
piecrust: add call_tree to CallReceipt
Browse files Browse the repository at this point in the history
  • Loading branch information
Eduardo Leegwater Simões committed Sep 26, 2023
1 parent 00b62d5 commit bff0670
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 21 deletions.
1 change: 1 addition & 0 deletions piecrust/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add `call_tree` to `CallReceipt` [#206]
- Expose `CallTree` and `CallTreeElem` in the public API [#206]
- Add `CallTreeIter` to improve iteration over call tree [#206]
- Add `panic` import implementation [#271]
Expand Down
4 changes: 2 additions & 2 deletions piecrust/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ fn c(

let ret = match instance.with_memory_mut(with_memory) {
Ok((ret_len, callee_spent)) => {
env.pop_callstack();
env.move_up_call_tree();
instance.set_remaining_points(caller_remaining - callee_spent);
ret_len
}
Expand All @@ -193,7 +193,7 @@ fn c(
io: Arc::new(io_err),
};
}
env.pop_callstack_prune();
env.move_up_prune_call_tree();
instance.set_remaining_points(caller_remaining - callee_limit);

ContractError::from(err).into()
Expand Down
45 changes: 26 additions & 19 deletions piecrust/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl Drop for Session {

#[derive(Debug)]
struct SessionInner {
call_stack: CallTree,
call_tree: CallTree,
instance_map: BTreeMap<ContractId, (*mut WrappedInstance, u64)>,
debug: Vec<String>,
data: SessionData,
Expand All @@ -103,7 +103,7 @@ impl Session {
data: SessionData,
) -> Self {
Self::from(SessionInner {
call_stack: CallTree::new(),
call_tree: CallTree::new(),
instance_map: BTreeMap::new(),
debug: vec![],
data,
Expand Down Expand Up @@ -323,14 +323,15 @@ impl Session {
return Err(InitalizationError("init call not allowed".into()));
}

let (data, points_spent) =
let (data, points_spent, call_tree) =
self.call_inner(contract, fn_name, fn_arg.into(), points_limit)?;
let events = mem::take(&mut self.inner.events);

Ok(CallReceipt {
points_limit,
points_spent,
events,
call_tree,
data,
})
}
Expand Down Expand Up @@ -420,7 +421,7 @@ impl Session {
}

fn clear_stack_and_instances(&mut self) {
self.inner.call_stack.clear();
self.inner.call_tree.clear();

while !self.inner.instance_map.is_empty() {
let (_, (instance, _)) =
Expand Down Expand Up @@ -485,7 +486,7 @@ impl Session {
}

pub(crate) fn nth_from_top(&self, n: usize) -> Option<CallTreeElem> {
self.inner.call_stack.nth_up(n)
self.inner.call_tree.nth_up(n)
}

/// Creates a new instance of the given contract, returning its memory
Expand Down Expand Up @@ -518,15 +519,15 @@ impl Session {
match instance {
Some(instance) => {
self.update_instance_count(contract_id, true);
self.inner.call_stack.push(CallTreeElem {
self.inner.call_tree.push(CallTreeElem {
contract_id,
limit,
mem_len: instance.mem_len(),
});
}
None => {
let mem_len = self.create_instance(contract_id)?;
self.inner.call_stack.push(CallTreeElem {
self.inner.call_tree.push(CallTreeElem {
contract_id,
limit,
mem_len,
Expand All @@ -536,25 +537,25 @@ impl Session {

Ok(self
.inner
.call_stack
.call_tree
.nth_up(0)
.expect("We just pushed an element to the stack"))
}

pub(crate) fn pop_callstack(&mut self) {
if let Some(element) = self.inner.call_stack.move_up() {
pub(crate) fn move_up_call_tree(&mut self) {
if let Some(element) = self.inner.call_tree.move_up() {
self.update_instance_count(element.contract_id, false);
}
}

pub(crate) fn pop_callstack_prune(&mut self) {
if let Some(element) = self.inner.call_stack.move_up_prune() {
pub(crate) fn move_up_prune_call_tree(&mut self) {
if let Some(element) = self.inner.call_tree.move_up_prune() {
self.update_instance_count(element.contract_id, false);
}
}

pub(crate) fn revert_callstack(&mut self) -> Result<(), std::io::Error> {
for elem in self.inner.call_stack.iter() {
for elem in self.inner.call_tree.iter() {
let instance = self
.instance(&elem.contract_id)
.expect("instance should exist");
Expand Down Expand Up @@ -617,7 +618,7 @@ impl Session {
fname: &str,
fdata: Vec<u8>,
limit: u64,
) -> Result<(Vec<u8>, u64), Error> {
) -> Result<(Vec<u8>, u64, CallTree), Error> {
let stack_element = self.push_callstack(contract, limit)?;
let instance = self
.instance(&stack_element.contract_id)
Expand All @@ -640,7 +641,7 @@ impl Session {
io: Arc::new(io_err),
};
}
self.pop_callstack_prune();
self.move_up_prune_call_tree();
err
})
.map_err(Error::normalize)?;
Expand All @@ -651,7 +652,7 @@ impl Session {
.get_remaining_points()
.expect("there should be remaining points");

for elem in self.inner.call_stack.iter() {
for elem in self.inner.call_tree.iter() {
let instance = self
.instance(&elem.contract_id)
.expect("instance should exist");
Expand All @@ -662,9 +663,11 @@ impl Session {
io: Arc::new(err),
})?;
}
self.pop_callstack();

Ok((ret, spent))
let mut call_tree = CallTree::new();
mem::swap(&mut self.inner.call_tree, &mut call_tree);

Ok((ret, spent, call_tree))
}

pub fn contract_metadata(
Expand All @@ -680,7 +683,7 @@ impl Session {
///
/// [`call`]: [`Session::call`]
/// [`call_raw`]: [`Session::call_raw`]
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Debug)]
pub struct CallReceipt<T> {
/// The amount of points spent in the execution of the call.
pub points_spent: u64,
Expand All @@ -689,6 +692,9 @@ pub struct CallReceipt<T> {

/// The events emitted during the execution of the call.
pub events: Vec<Event>,
/// The call tree produced during the execution.
pub call_tree: CallTree,

/// The data returned by the called contract.
pub data: T,
}
Expand All @@ -709,6 +715,7 @@ impl CallReceipt<Vec<u8>> {
points_spent: self.points_spent,
points_limit: self.points_limit,
events: self.events,
call_tree: self.call_tree,
data,
})
}
Expand Down

0 comments on commit bff0670

Please sign in to comment.