Skip to content

Commit 648283e

Browse files
authored
Add support for ext_terminate (#352)
* [core, lang] add support for ext_terminate * [lang] apply rustfmt
1 parent d55fcd0 commit 648283e

File tree

6 files changed

+60
-0
lines changed

6 files changed

+60
-0
lines changed

core/src/env/api.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,25 @@ pub fn restore_contract<T>(
395395
})
396396
}
397397

398+
/// Terminates the existence of the currently executed smart contract.
399+
///
400+
/// This removes the calling account and transfers all remaining balance
401+
/// to the given beneficiary.
402+
///
403+
/// # Note
404+
///
405+
/// This function never returns. Either the termination was successful and the
406+
/// execution of the destroyed contract is halted. Or it failed during the termination
407+
/// which is considered fatal and results in a trap + rollback.
408+
pub fn terminate_contract<T>(beneficiary: T::AccountId) -> !
409+
where
410+
T: EnvTypes,
411+
{
412+
<EnvInstance as OnInstance>::on_instance(|instance| {
413+
TypedEnv::terminate_contract::<T>(instance, beneficiary)
414+
})
415+
}
416+
398417
/// Transfers value from the contract to the destination account ID.
399418
///
400419
/// # Note

core/src/env/backend.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,15 @@ pub trait TypedEnv: Env {
234234
) where
235235
T: EnvTypes;
236236

237+
/// Terminates a smart contract.
238+
///
239+
/// # Note
240+
///
241+
/// For more details visit: [`ink_core::env::terminate_contract`]
242+
fn terminate_contract<T>(&mut self, beneficiary: T::AccountId) -> !
243+
where
244+
T: EnvTypes;
245+
237246
/// Transfers value from the contract to the destination account ID.
238247
///
239248
/// # Note

core/src/env/engine/off_chain/impls.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,13 @@ impl TypedEnv for EnvInstance {
249249
unimplemented!("off-chain environment does not support contract instantiation")
250250
}
251251

252+
fn terminate_contract<T>(&mut self, _beneficiary: T::AccountId) -> !
253+
where
254+
T: EnvTypes,
255+
{
256+
unimplemented!("off-chain environment does not support contract termination")
257+
}
258+
252259
fn restore_contract<T>(
253260
&mut self,
254261
_account_id: T::AccountId,

core/src/env/engine/on_chain/ext.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ mod sys {
7777
delta_ptr: u32,
7878
delta_count: u32,
7979
);
80+
pub fn ext_terminate(beneficiary_ptr: u32, beneficiary_len: u32) -> !;
8081

8182
pub fn ext_dispatch_call(call_ptr: u32, call_len: u32);
8283

@@ -243,6 +244,10 @@ pub fn restore_to(
243244
}
244245
}
245246

247+
pub fn terminate(beneficiary: &[u8]) -> ! {
248+
unsafe { sys::ext_terminate(beneficiary.as_ptr() as u32, beneficiary.len() as u32) }
249+
}
250+
246251
pub fn dispatch_call(call: &[u8]) {
247252
unsafe { sys::ext_dispatch_call(call.as_ptr() as u32, call.len() as u32) }
248253
}

core/src/env/engine/on_chain/impls.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,14 @@ impl TypedEnv for EnvInstance {
330330
ext::restore_to(account_id, code_hash, rent_allowance, filtered_keys);
331331
}
332332

333+
fn terminate_contract<T>(&mut self, beneficiary: T::AccountId) -> !
334+
where
335+
T: EnvTypes,
336+
{
337+
self.encode_into_buffer(beneficiary);
338+
ext::terminate(&self.buffer[..]);
339+
}
340+
333341
fn transfer<T>(&mut self, destination: T::AccountId, value: T::Balance) -> Result<()>
334342
where
335343
T: EnvTypes,

lang/src/env_access.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,18 @@ where
263263
env::restore_contract::<T>(account_id, code_hash, rent_allowance, filtered_keys)
264264
}
265265

266+
/// Terminates the existence of a smart contract.
267+
///
268+
/// # Note
269+
///
270+
/// For more details visit: [`ink_core::env::terminate_contract`]
271+
pub fn terminate_contract(self, beneficiary: T::AccountId) -> !
272+
where
273+
T: EnvTypes,
274+
{
275+
env::terminate_contract::<T>(beneficiary)
276+
}
277+
266278
/// Transfers value from the contract to the destination account ID.
267279
///
268280
/// # Note

0 commit comments

Comments
 (0)