Maintenance Loop in an EOSIO Smart Contract EnvironmentYaroslav ErohinBlockedUnblockFollowFollowingJun 13Implementing periodic updates for decentralised applications on EOSIO blockchainSometimes smart contracts require actions to be processed after a certain delay or in a periodic fashion.
Real life examples include the return of EOS tokens to user’s balance after the unstaking period, processing REX loans and sell orders and channelling name bid proceeds into REX.
A maintenance function that runs periodically is required to solve a problem like this, but blockchain architecture presents multiple obstacles.
Investigating PossibilitiesOne of the possible implementations that we’ve investigated were deferred transactions.
Deferred transactions are scheduled to run after a specified delay, and they can even schedule more deferred transactions.
It all sounds great, except there’s one problem: a deferred transaction is not guaranteed to run on the blockchain.
System contracts implement returning unstaked EOS tokens or running a multi-sig transaction using deferred transactions, and those actions sometimes fail.
The resource payer account might not have enough resources, like CPU or RAM, the transaction might not meet specified conditions, or some other error might occur.
Sometimes your unstaked tokens don’t return to you automatically (then you have to claim them manually), and even the multi-sig transactions while deploying system contract with REX update have failed for not having enough resources.
This approach does not allow to build a sustainable and predictable maintenance system.
Furthermore, deferred transactions will become even less reliable in the future and it is not recommended to use them in development of new smart contracts.
Taking Inspiration from the System ContractREX implemented maintenance loop with runrex method of the system contract.
Every time that method is called, it processes a specified number of items in each category: expired loans, sell orders, and transfer of name bid proceeds.
What allows this method to maintain the whole system is that it’s called every time any user makes a REX-related transaction.
For example, every time you buy or sell REX, you process up to 2 items of each category.
System contract also has a direct rexexec action that triggers runrex method.
If you would like to contribute some of your CPU to help REX processing, you can run it specifying your account name and a maximum number of items you wish to process.
BUCK Protocol’s Maintenance LoopBUCK Protocol’s central processing system revolves around Oracle price updates.
With every update, there might be different items to process.
Liquidation is the first and most important thing that gets processed.
When EOS price goes down, there comes a chance that some CDP’s Debt Collateral Ratio (which defines ratio of collateral to debt) might drop below the minimal requirement.
In this case, the CDP must be partially liquidated.
After liquidation is complete, requests to reparametrize CDPs are processed.
Those requests have to be processed after the next price update, so people can’t take advantage of short-term EOS price spikes.
After requests are processed, then comes redemption.
In rare cases of $BUCK price going up too high, the mechanism of redemption makes sure to bring the peg back to $1.
There is also exchange, processing buy and sell orders and collection of taxes from debtor CDPs.
Dealing with CPU LimitationsBlockchain architecture does not allow a transaction to run forever; in fact, EOSIO limits them to only 30ms of CPU time.
If any transaction attempts to run for longer, it fails to execute entirely.
Just as in REX, we have a run method and every time a user is interacting with BUCK Protocol, this method is run to perform maintenance.
Every $BUCK transfer is set to process up to 3 pending items, and other light-weight requests like creating a reparametrization or redemption request process up to 10 items.
The optimal number of items to process is still an open question for us, and we will be updating it to keep the contract running.
To help the system in the beginning, with every price update our Oracle immediately calls run action to process up to 50 items.
It helps the system to stay afloat until a sustainable amount of transactions is happening regularly.
Later on, especially after a properly decentralised Oracle is implemented and users use the system with more regularity, we might stand aside and put the whole maintenance loop on the shoulders of the community.