mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 15:11:03 +00:00
srml-contracts: Deferred actions (#3255)
* Switch to deferred actions * Make restore_to a deferred action. * Bump version. * Review fixes.
This commit is contained in:
committed by
Gavin Wood
parent
780942192e
commit
de02aee156
@@ -586,6 +586,87 @@ define_env!(Env, <E: Ext>,
|
||||
Ok(())
|
||||
},
|
||||
|
||||
// Record a request to restore the caller contract to the specified contract.
|
||||
//
|
||||
// At the finalization stage, i.e. when all changes from the extrinsic that invoked this
|
||||
// contract are commited, this function will compute a tombstone hash from the caller's
|
||||
// storage and the given code hash and if the hash matches the hash found in the tombstone at
|
||||
// the specified address - kill the caller contract and restore the destination contract and set
|
||||
// the specified `rent_allowance`. All caller's funds are transfered to the destination.
|
||||
//
|
||||
// This function doesn't perform restoration right away but defers it to the end of the
|
||||
// transaction. If there is no tombstone in the destination address or if the hashes don't match
|
||||
// then restoration is cancelled and no changes are made.
|
||||
//
|
||||
// `dest_ptr`, `dest_len` - the pointer and the length of a buffer that encodes `T::AccountId`
|
||||
// with the address of the to be restored contract.
|
||||
// `code_hash_ptr`, `code_hash_len` - the pointer and the length of a buffer that encodes
|
||||
// a code hash of the to be restored contract.
|
||||
// `rent_allowance_ptr`, `rent_allowance_len` - the pointer and the length of a buffer that
|
||||
// encodes the rent allowance that must be set in the case of successful restoration.
|
||||
// `delta_ptr` is the pointer to the start of a buffer that has `delta_count` storage keys
|
||||
// laid out sequentially.
|
||||
ext_restore_to(
|
||||
ctx,
|
||||
dest_ptr: u32,
|
||||
dest_len: u32,
|
||||
code_hash_ptr: u32,
|
||||
code_hash_len: u32,
|
||||
rent_allowance_ptr: u32,
|
||||
rent_allowance_len: u32,
|
||||
delta_ptr: u32,
|
||||
delta_count: u32
|
||||
) => {
|
||||
let dest = {
|
||||
let dest_buf = read_sandbox_memory(ctx, dest_ptr, dest_len)?;
|
||||
<<E as Ext>::T as system::Trait>::AccountId::decode(&mut &dest_buf[..])
|
||||
.ok_or_else(|| sandbox::HostError)?
|
||||
};
|
||||
let code_hash = {
|
||||
let code_hash_buf = read_sandbox_memory(ctx, code_hash_ptr, code_hash_len)?;
|
||||
<CodeHash<<E as Ext>::T>>::decode(&mut &code_hash_buf[..])
|
||||
.ok_or_else(|| sandbox::HostError)?
|
||||
};
|
||||
let rent_allowance = {
|
||||
let rent_allowance_buf = read_sandbox_memory(
|
||||
ctx,
|
||||
rent_allowance_ptr,
|
||||
rent_allowance_len
|
||||
)?;
|
||||
BalanceOf::<<E as Ext>::T>::decode(&mut &rent_allowance_buf[..])
|
||||
.ok_or_else(|| sandbox::HostError)?
|
||||
};
|
||||
let delta = {
|
||||
// We don't use `with_capacity` here to not eagerly allocate the user specified amount
|
||||
// of memory.
|
||||
let mut delta = Vec::new();
|
||||
let mut key_ptr = delta_ptr;
|
||||
|
||||
for _ in 0..delta_count {
|
||||
const KEY_SIZE: usize = 32;
|
||||
|
||||
// Read the delta into the provided buffer and collect it into the buffer.
|
||||
let mut delta_key: StorageKey = [0; KEY_SIZE];
|
||||
read_sandbox_memory_into_buf(ctx, key_ptr, &mut delta_key)?;
|
||||
delta.push(delta_key);
|
||||
|
||||
// Offset key_ptr to the next element.
|
||||
key_ptr = key_ptr.checked_add(KEY_SIZE as u32).ok_or_else(|| sandbox::HostError)?;
|
||||
}
|
||||
|
||||
delta
|
||||
};
|
||||
|
||||
ctx.ext.note_restore_to(
|
||||
dest,
|
||||
code_hash,
|
||||
rent_allowance,
|
||||
delta,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
},
|
||||
|
||||
// Returns the size of the scratch buffer.
|
||||
//
|
||||
// For more details on the scratch buffer see `ext_scratch_copy`.
|
||||
|
||||
Reference in New Issue
Block a user