Skip to content

Commit

Permalink
fix(tick): add tick cron handler source code and update tick state to…
Browse files Browse the repository at this point in the history
… increment based on epoch index
  • Loading branch information
dtfiedler authored and dtfiedler committed Jun 10, 2024
1 parent 3a7b332 commit 04d26aa
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 30 deletions.
68 changes: 38 additions & 30 deletions contract/src/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Vaults = Vaults or {}
GatewayRegistry = GatewayRegistry or {}
NameRegistry = NameRegistry or {}
Epochs = Epochs or {}
LastTickedEpoch = LastTickedEpoch or 0

local utils = require("utils")
local json = require("json")
Expand Down Expand Up @@ -660,37 +661,44 @@ end)
Handlers.add("tick", utils.hasMatchingTag("Action", "Tick"), function(msg)
local timestamp = tonumber(msg.Timestamp)
-- TODO: how do we make this update atomic so that the state is changed all or nothing (should we?)
local previousState = {
Balances = utils.deepCopy(Balances),
Vaults = utils.deepCopy(Vaults),
GatewayRegistry = utils.deepCopy(GatewayRegistry),
NameRegistry = utils.deepCopy(NameRegistry),
Epochs = utils.deepCopy(Epochs),
DemandFactor = utils.deepCopy(DemandFactor),
}
local function tickState(timestamp)
-- arns.pruneRecords(timestamp)
-- arns.pruneReservedNames(timestamp)
-- vaults.pruneVaults(timestamp)
-- gar.pruneGateways(timestamp)
-- demand.updateDemandFactor(timestamp)
local lastTickedEpochIndex = LastTickedEpoch
local currentEpochIndex = epochs.getEpochIndexForTimestamp(timestamp)
local function tickState(timestamp, blockHeight, hashchain)
arns.pruneRecords(timestamp)
arns.pruneReservedNames(timestamp)
vaults.pruneVaults(timestamp)
gar.pruneGateways(timestamp)
demand.updateDemandFactor(timestamp)
epochs.distributeRewardsForEpoch(timestamp)
epochs.createEpoch(timestamp, tonumber(msg["Block-Height"]), msg["Hash-Chain"])
end

local status, result = pcall(tickState, timestamp)
if status then
ao.send({ Target = msg.From, Data = json.encode(result) })
else
-- reset the state to previous state
Balances = previousState.Balances
Vaults = previousState.Vaults
GatewayRegistry = previousState.GatewayRegistry
NameRegistry = previousState.NameRegistry
Epochs = previousState.Epochs
DemandFactor = previousState.DemandFactor

ao.send({ Target = msg.From, Data = json.encode(result) })
epochs.createEpoch(timestamp, tonumber(blockHeight), hashchain)
end

-- tick and distribute rewards for every index between the last ticked epoch and the current epoch
for i = lastTickedEpochIndex + 1, currentEpochIndex do
local previousState = {
Balances = utils.deepCopy(Balances),
Vaults = utils.deepCopy(Vaults),
GatewayRegistry = utils.deepCopy(GatewayRegistry),
NameRegistry = utils.deepCopy(NameRegistry),
Epochs = utils.deepCopy(Epochs),
DemandFactor = utils.deepCopy(DemandFactor),
}
local _, _, epochDistributionTimestamp = epochs.getEpochTimestampsForIndex(i)
-- TODO: if we need to "recover" epochs, we can't rely on just the current message hashchain and block height
local status, result = pcall(tickState, epochDistributionTimestamp, msg["Block-Height"], msg["Hash-Chain"])
if status then
ao.send({ Target = msg.From, Data = json.encode(result) })
LastTickedEpoch = i -- update the last ticked state
else
-- reset the state to previous state
Balances = previousState.Balances
Vaults = previousState.Vaults
GatewayRegistry = previousState.GatewayRegistry
NameRegistry = previousState.NameRegistry
Epochs = previousState.Epochs
DemandFactor = previousState.DemandFactor
ao.send({ Target = msg.From, Data = json.encode(result) })
end
end
end)

Expand Down
17 changes: 17 additions & 0 deletions cron/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Cron Handler

This process is responsible for sending messages to the AO/IO contract on a cron basis to ensure state is properly ticked throughout Epochs.

### Loading in AOS

Example loading in AOS:

```bash
aos devnet-tick-state --cron 1-hour
```

The `Target` object can be manually modified by running.

```bash
aos> Target="" -- insert process ID to tick
```
8 changes: 8 additions & 0 deletions cron/main.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Target = Target or "GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelVLB6GcRGrHc"
Handlers.add(
"CronTick", -- handler name
Handlers.utils.hasMatchingTag("Action", "Cron"), -- handler pattern to identify cron message
function () -- handler task to execute on cron message
ao.send({Target=Target, Action= "Tick"})
end
)

0 comments on commit 04d26aa

Please sign in to comment.