Closed jon-chuang closed 1 year ago
@jon-chuang May I ask what is the use case that this would solve? I find that there is often detour solution for this kind of issues, for example Pancake swap auto compound with a faucet to trigger things with an incentive.
Yeah, this can be easily replaced with a crank. Many liquidity mining reward payouts use cranks nowadays
Another use case for this would be recurring payments for subscriptions to digital services like Youtube or IRL services like the gym. It sounds like an overkill to me that everyone in the world that wants to accept a payment through solana, needs to have their own backend that triggers on-chain programs.
Problem
Although it is easy for an off-chain agent to perform the role of cron in scheduling transactions, many would benefit from the ease of use of a scheduling functionality available on-chain.
Proposed Solution
Maintain a Hashmap of
SlotCronJobList
accounts and "sleep" till next job.SlotCronJobList
s contain theprev_job_slot
andnext_job_slot
fields, so that the hashmap can be updated in a doubly-linked list fashion. Essentially, we are implementing a queue maintaining job order, where execution for a job can only start after a timestamp, but potentially run any time after.A job can either
skip_if_missed_slot
orreschedule
, orskip_if_missed_n_slots(u64)
. i.e.2nd and 4th can be captured by 3rd and 5th, I guess.
CronJobs also have another orthogonal param:
After which the jobs are deleted.
Every cron job item processing invocation is paid for by a corresponding fee-paying account.
If an account has insufficient balance, it deletes the jobs.
So all runtimes do the following:
There is a central cron account. Cron program updates the
next_job_slot
. Every slot, each validator checks the if the slot is thenext_job_slot
. If so, it wakes up. This way, we can avoid unnecessary BTree queries.Everytime a new job is inserted, if its
job_slot
is <next_job_slot
,next_job_slot
is updated, etcIf a block is skipped, the cron runtime will detect a discrepancy in that
next_job_slot
is <current_slot
and attempts to execute jobs from the skipped next job slot till present, skipping those that are marked asskip_if_missed_slot
. We can get toreschedule
in the future. The default is to execute the jobs belatedly, in order.With regards to amount of crontab work not exceeding capacity, for a given slot, this would have to be first come first serve.
But anw since crontab processes transactions, it's equivalent to say it's hard to guarantee the amount of txs won't exceed capacity of the network.
Nonetheless, I can definitely preempt a potential DDoS attack which is to spam TXs to schedule cronjobs for a particular slot. But this is fixable by implementing a
const MAX_CRON_JOBS_PER_SLOT: u64 = 1 << 14
. And we returnCronJobError::CapacityForSlotExceeded
if we hit that limit.Users need to know that there is no guarantee a cronjob would execute in a particular epoch, but then again, that is true also for a tx
Access control: So the protocol I've just thought of works as follows: 1.To register your account with the cron program, first, you have to: atomically transfer ownership to the cron program + register your ownership in the cron registry.
What is Cron after all but a pupeteer?
I'm starting to conceptualise it as having a puppeteer program that acts on your behalf on-chain. It has its own registry of access control, similar to other programs with derived addresses.
Meaning - doesn't an SPL-token account need to have the corresponding registry/from pubkey account-derivation method?
One of the most important thing this means is you can schedule txs to be signed at arbitrarily chosen times.
In a distant future this could also mean you can listen to on-chain events and react autonomously, even if that means signing (authorising) txs.
You need to use cron to do everything on your behalf - create SPL-token accounts etc.
Cron would need to be integrated into wallets and need to be lightweight so that it incurs a minimal overhead to perform arbitrary actions on the user's behalf.