Replies: 3 comments 6 replies
-
To go further on future usage specification i would like to add:
|
Beta Was this translation helpful? Give feedback.
-
It might be a good idea to add a function that retrieves the first available slot bookable based on the gas ? |
Beta Was this translation helpful? Give feedback.
-
Given that a significant use case involves scheduling recurring calls outside of the one-week bookable window, the proposed solution of using a deferred call to book another future call presents a major challenge: How can we ensure that the future booking will succeed?
To address this, I propose adding an additional feature: a recursive_deferred_call that accepts a period as an argument. The recursive scheduling would be managed by the node itself, outside of the runtime environment. This approach would separate the scheduling functionality from the execution of the task, ensuring that even if the task fails, the next scheduled call is still triggered. Of course, this does not resolve issues related to insufficient coins for future calls. I didn't though about how the bookable fee of a such feature could be computed, but i think the idea worth to be considered. |
Beta Was this translation helpful? Give feedback.
-
Intro
The current ASC model allows for rich wakeup conditions, execution ranges and so on.. but does not ensure 100% execution probability under congestion. We introduce Deferred Calls to complement existing ASCs. Deferred calls work this way:
General considerations
ABIs
deferred_call_quote(target_slot, max_gas) -> Option<Amount>
: computes the coin cost of a deferred call. The retun value indicates whether the slot can be used (Some(X)) or cannot fit thatmax_gas
anymore (None). Returns None if the slot is in the past, is the current slot (too late!), or is too far in the future by more thandeferred_call_max_future_slots
slots.deferred_call_register(target_slot, target_addr, target_func, params, coins, max_gas) -> CallID
: registers a deferred call and returns its ID. This function spendscoins + deferred_call_quote(target_slot, max_gas).unwrap()
from the caller, fails if the balance is insufficient or if the quote would return None.deferred_call_exists(CallID) -> bool
: returns true only if the deferred call is still exists and was not cancelleddeferred_call_cancel(CallID)
: cancels a deferred call. Can only be called by the creator of the deferred call. Reimbursescoins
to the sender but not the deferred call fee to avoid spam. Cancelled items are not removed from storage to avoid manipulation, just ignored when it is their turn to be executed.Emission
When
deferred_call_register
is called:deferred_call_quote(target_slot, max_gas) == None
deferred_call_quote(target_slot, max_gas).unwrap() + coins
from the address on top of the call stack, fail if it can't be debitedExecution
Execution sequence of a slot
s
:s
since restart checkpoint (if any):D
targeting slots
in index order within the slot:D
is not marked as cancelled:D
(transfercoins
to target + run the function)coins
back to the senderD
from the dbs
, execute the blockmax_async_gas
andmax_block_gas
, and the latter can be used in full in case of block miss)Storage
We need to limit how far in the future calls can be programmed according to the formula:
where:
max_storage_space
is a protocol constant on how much storage space we want to allocate to deferred callsmax_deferred_call_size
is a protocol constant about the max size of a deferred call item in storagetotal_slot_gas
is the total gas of a slot (protocol constant)deferred_call_abi_gas
is a protocol constant defining the gas used by thedefer_call
ABI.Deferred call ID
Deferred calls need to be:
So let's define the deferred call ID as:
binary_id = [version as u64.to_be_bytes][target_slot as Slot.to_bytes_key][index_in_target_slot as u64.to_be_bytes][trail_hash]
text_id = 'D' + bs58check(binary_id)
The binary ID is used directly in DB for sorting and access.
Fee computation and usage
Beta Was this translation helpful? Give feedback.
All reactions