mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 15:11:02 +00:00
Add ext_terminate (#5234)
With this patch forward this will be the only way for a contract to destroy itself. This patch therefore changes the semantics of all other contract initiated balance transfers to fail if they would bring the caller below the existential deposit.
This commit is contained in:
committed by
GitHub
parent
e91d4be998
commit
601f2538c6
@@ -41,6 +41,9 @@ enum SpecialTrap {
|
||||
Return(Vec<u8>),
|
||||
/// Signals that trap was generated because the contract exhausted its gas limit.
|
||||
OutOfGas,
|
||||
/// Signals that a trap was generated in response to a succesful call to the
|
||||
/// `ext_terminate` host function.
|
||||
Termination,
|
||||
}
|
||||
|
||||
/// Can only be used for one call.
|
||||
@@ -83,14 +86,20 @@ pub(crate) fn to_execution_result<E: Ext>(
|
||||
status: STATUS_SUCCESS,
|
||||
data,
|
||||
})
|
||||
}
|
||||
},
|
||||
Some(SpecialTrap::Termination) => {
|
||||
return Ok(ExecReturnValue {
|
||||
status: STATUS_SUCCESS,
|
||||
data: Vec::new(),
|
||||
})
|
||||
},
|
||||
Some(SpecialTrap::OutOfGas) => {
|
||||
return Err(ExecError {
|
||||
reason: "ran out of gas during contract execution".into(),
|
||||
buffer: runtime.scratch_buf,
|
||||
})
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
None => (),
|
||||
}
|
||||
|
||||
// Check the exact type of the error.
|
||||
@@ -443,6 +452,9 @@ define_env!(Env, <E: Ext>,
|
||||
// changes made by the called contract are reverted. The scratch buffer is filled with the
|
||||
// output data returned by the called contract, even in the case of a failure status.
|
||||
//
|
||||
// This call fails if it would bring the calling contract below the existential deposit.
|
||||
// In order to destroy a contract `ext_terminate` must be used.
|
||||
//
|
||||
// If the contract traps during execution or otherwise fails to complete successfully, then
|
||||
// this function clears the scratch buffer and returns 0x0100. As with a failure status, any
|
||||
// state changes made by the called contract are reverted.
|
||||
@@ -523,6 +535,9 @@ define_env!(Env, <E: Ext>,
|
||||
// of the newly instantiated contract. In the case of a failure status, the scratch buffer is
|
||||
// cleared.
|
||||
//
|
||||
// This call fails if it would bring the calling contract below the existential deposit.
|
||||
// In order to destroy a contract `ext_terminate` must be used.
|
||||
//
|
||||
// If the contract traps during execution or otherwise fails to complete successfully, then
|
||||
// this function clears the scratch buffer and returns 0x0100. As with a failure status, any
|
||||
// state changes made by the called contract are reverted.
|
||||
@@ -601,6 +616,30 @@ define_env!(Env, <E: Ext>,
|
||||
}
|
||||
},
|
||||
|
||||
// Remove the calling account and transfer remaining balance.
|
||||
//
|
||||
// This function never returns. Either the termination was successful and the
|
||||
// execution of the destroyed contract is halted. Or it failed during the termination
|
||||
// which is considered fatal and results in a trap + rollback.
|
||||
//
|
||||
// - beneficiary_ptr: a pointer to the address of the beneficiary account where all
|
||||
// where all remaining funds of the caller are transfered.
|
||||
// Should be decodable as an `T::AccountId`. Traps otherwise.
|
||||
// - beneficiary_len: length of the address buffer.
|
||||
ext_terminate(
|
||||
ctx,
|
||||
beneficiary_ptr: u32,
|
||||
beneficiary_len: u32
|
||||
) => {
|
||||
let beneficiary: <<E as Ext>::T as frame_system::Trait>::AccountId =
|
||||
read_sandbox_memory_as(ctx, beneficiary_ptr, beneficiary_len)?;
|
||||
|
||||
if let Ok(_) = ctx.ext.terminate(&beneficiary, ctx.gas_meter) {
|
||||
ctx.special_trap = Some(SpecialTrap::Termination);
|
||||
}
|
||||
Err(sp_sandbox::HostError)
|
||||
},
|
||||
|
||||
// Save a data buffer as a result of the execution, terminate the execution and return a
|
||||
// successful result to the caller.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user