Skip to content

Commit 99ab889

Browse files
committed
make ManagedCallStack a shared prt
1 parent c0a3b2e commit 99ab889

File tree

2 files changed

+34
-39
lines changed

2 files changed

+34
-39
lines changed

lang/codegen/src/trait_definition.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,11 @@ fn generate_wrapper(ink_trait: ItemTrait, mock_type: Option<TokenStream>) -> pro
272272
Some(_mock_ty) => quote! {
273273
mock_env :: with(|ctx| {
274274
let mut mock_ref = ctx.register.get_mut(self).expect("not an address of mocked contract");
275-
ctx.stack.borrow_mut().push(&self);
275+
ctx.stack.push(&self);
276276
let result = mock_ref.borrow_mut(). #message_ident (
277277
#( #input_bindings , )*
278278
);
279-
ctx.stack.borrow_mut().pop();
279+
ctx.stack.pop();
280280
result
281281
}).expect("mock object not set")
282282
},
@@ -335,9 +335,7 @@ fn generate_wrapper(ink_trait: ItemTrait, mock_type: Option<TokenStream>) -> pro
335335
quote! {
336336
#[cfg(any(test, feature = "mockable"))]
337337
pub struct Context {
338-
pub stack: std::rc::Rc<std::cell::RefCell<
339-
::openbrush::traits::mock::ManagedCallStack
340-
>>,
338+
pub stack: ::openbrush::traits::mock::SharedCallStack,
341339
pub register: std::collections::BTreeMap<
342340
::openbrush::traits::AccountId,
343341
std::rc::Rc<std::cell::RefCell< #ty >>
@@ -351,7 +349,7 @@ fn generate_wrapper(ink_trait: ItemTrait, mock_type: Option<TokenStream>) -> pro
351349

352350
#[cfg(any(test, feature = "mockable"))]
353351
pub fn using<F: FnOnce()>(
354-
stack: std::rc::Rc<std::cell::RefCell<::openbrush::traits::mock::ManagedCallStack>>,
352+
stack: ::openbrush::traits::mock::SharedCallStack,
355353
f: F
356354
) {
357355
let mut env = Context {

lang/src/traits.rs

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -107,43 +107,40 @@ pub mod mock {
107107
}
108108

109109
/// A managed call stack for mocking cross-contract call in test environment
110-
pub struct ManagedCallStack {
111-
stack: Vec<MockCallContext>,
110+
#[derive(Clone)]
111+
pub struct SharedCallStack {
112+
stack: Rc<RefCell<Vec<MockCallContext>>>,
112113
}
113114

114-
impl ManagedCallStack {
115+
impl SharedCallStack {
115116
/// Crates a call stack with the default `account`
116117
pub fn new(account: AccountId) -> Self {
117-
ManagedCallStack {
118-
stack: alloc::vec![MockCallContext {
118+
SharedCallStack {
119+
stack: Rc::new(RefCell::new(alloc::vec![MockCallContext {
119120
level: 0,
120121
caller: None,
121122
callee: account,
122-
}],
123+
}])),
123124
}
124125
}
125126

126-
/// Creates a call stack with the default `account` and returns a shared reference
127-
pub fn create_shared(account: AccountId) -> Rc<RefCell<Self>> {
128-
Rc::new(RefCell::new(Self::new(account)))
129-
}
130-
131127
/// Changes the caller account
132128
///
133129
/// Only allowed outside any contract call (when the stack is empty).
134-
pub fn switch_account(&mut self, account: AccountId) -> Result<(), ()> {
135-
if self.stack.len() != 1 {
130+
pub fn switch_account(&self, account: AccountId) -> Result<(), ()> {
131+
let mut stack = self.stack.borrow_mut();
132+
if stack.len() != 1 {
136133
return Err(())
137134
}
138-
let ctx = self.stack.get_mut(0).ok_or(())?;
135+
let ctx = stack.get_mut(0).ok_or(())?;
139136
ctx.callee = account;
140137
Ok(())
141138
}
142139

143140
/// Pushes a new call frame
144-
pub fn push(&mut self, callee: &AccountId) {
145-
let parent_ctx = self.peek().clone();
146-
self.stack.push(MockCallContext {
141+
pub fn push(&self, callee: &AccountId) {
142+
let parent_ctx = self.peek();
143+
self.stack.borrow_mut().push(MockCallContext {
147144
level: parent_ctx.level + 1,
148145
caller: Some(parent_ctx.callee),
149146
callee: callee.clone(),
@@ -152,9 +149,9 @@ pub mod mock {
152149
}
153150

154151
/// Pops the call frame and returns the frame
155-
pub fn pop(&mut self) -> Option<MockCallContext> {
156-
if self.stack.len() > 1 {
157-
let ctx = self.stack.pop();
152+
pub fn pop(&self) -> Option<MockCallContext> {
153+
if self.stack.borrow().len() > 1 {
154+
let ctx = self.stack.borrow_mut().pop();
158155
self.sync_to_ink();
159156
ctx
160157
} else {
@@ -163,8 +160,8 @@ pub mod mock {
163160
}
164161

165162
/// Peeks the current call frame
166-
pub fn peek(&self) -> &MockCallContext {
167-
self.stack.last().expect("stack is never empty; qed.")
163+
pub fn peek(&self) -> MockCallContext {
164+
self.stack.borrow().last().cloned().expect("stack is never empty; qed.")
168165
}
169166

170167
/// Syncs the top call frame to ink testing environment
@@ -182,19 +179,19 @@ pub mod mock {
182179
pub struct Addressable<T> {
183180
inner: Rc<RefCell<T>>,
184181
id: AccountId,
185-
stack: Rc<RefCell<ManagedCallStack>>,
182+
stack: SharedCallStack,
186183
}
187184

188185
impl<T> Addressable<T> {
189186
/// Wraps a contract reference with id and a shared call stack
190-
pub fn new(id: AccountId, inner: Rc<RefCell<T>>, stack: Rc<RefCell<ManagedCallStack>>) -> Self {
187+
pub fn new(id: AccountId, inner: Rc<RefCell<T>>, stack: SharedCallStack) -> Self {
191188
Addressable { inner, id, stack }
192189
}
193190

194191
/// Wraps a native contract object with a simple id
195192
///
196193
/// The account id of the contract will be the `id` with zero-padding.
197-
pub fn create_native(id: u8, inner: T, stack: Rc<RefCell<ManagedCallStack>>) -> Self {
194+
pub fn create_native(id: u8, inner: T, stack: SharedCallStack) -> Self {
198195
Addressable {
199196
inner: Rc::new(RefCell::new(inner)),
200197
id: naive_id(id),
@@ -225,12 +222,12 @@ pub mod mock {
225222
/// Push a call stack when the `Ref` in scope
226223
pub struct ScopedRef<'b, T: 'b> {
227224
inner: Ref<'b, T>,
228-
stack: Rc<RefCell<ManagedCallStack>>,
225+
stack: SharedCallStack,
229226
}
230227

231228
impl<'b, T> ScopedRef<'b, T> {
232-
fn new(inner: Ref<'b, T>, address: &AccountId, stack: Rc<RefCell<ManagedCallStack>>) -> Self {
233-
stack.borrow_mut().push(address);
229+
fn new(inner: Ref<'b, T>, address: &AccountId, stack: SharedCallStack) -> Self {
230+
stack.push(address);
234231
Self { inner, stack }
235232
}
236233
}
@@ -244,19 +241,19 @@ pub mod mock {
244241

245242
impl<'b, T> Drop for ScopedRef<'b, T> {
246243
fn drop(&mut self) {
247-
self.stack.borrow_mut().pop().expect("pop never fails");
244+
self.stack.pop().expect("pop never fails");
248245
}
249246
}
250247

251248
/// Push a call stack when the `RefMut` in scope
252249
pub struct ScopedRefMut<'b, T: 'b> {
253250
inner: RefMut<'b, T>,
254-
stack: Rc<RefCell<ManagedCallStack>>,
251+
stack: SharedCallStack,
255252
}
256253

257254
impl<'b, T> ScopedRefMut<'b, T> {
258-
fn new(inner: RefMut<'b, T>, address: &AccountId, stack: Rc<RefCell<ManagedCallStack>>) -> Self {
259-
stack.borrow_mut().push(address);
255+
fn new(inner: RefMut<'b, T>, address: &AccountId, stack: SharedCallStack) -> Self {
256+
stack.push(address);
260257
Self { inner, stack }
261258
}
262259
}
@@ -276,7 +273,7 @@ pub mod mock {
276273

277274
impl<'b, T> Drop for ScopedRefMut<'b, T> {
278275
fn drop(&mut self) {
279-
self.stack.borrow_mut().pop().expect("pop never fails");
276+
self.stack.pop().expect("pop never fails");
280277
}
281278
}
282279

0 commit comments

Comments
 (0)