Skip to content

Commit

Permalink
fix(epochs): handle unix timestsamps in ms and convert to seconds (#22)
Browse files Browse the repository at this point in the history
This is just precaution to ensure the contract is always dealing in ms
  • Loading branch information
dtfiedler authored Jul 11, 2024
2 parents d822ad6 + 9930382 commit 434c63f
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 14 deletions.
30 changes: 17 additions & 13 deletions spec/epochs_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ local testSettings = {
label = "test",
delegateRewardShareRatio = 0,
}
local startTimestamp = 0
local startTimestamp = 1704092400000
local protocolBalance = 500000000 * 1000000
local hashchain = "NGU1fq_ssL9m6kRbRU1bqiIDBht79ckvAwRMGElkSOg" -- base64 of "some sample hash"

Expand All @@ -23,9 +23,9 @@ describe("epochs", function()
}
_G.Epochs = {
[0] = {
startTimestamp = 0,
endTimestamp = 100,
distributionTimestamp = 115,
startTimestamp = 1704092400000,
endTimestamp = 1704092400100,
distributionTimestamp = 1704092400115,
prescribedObservers = {},
distributions = {},
observations = {
Expand All @@ -42,7 +42,7 @@ describe("epochs", function()
epochs.updateEpochSettings({
prescribedNameCount = 5,
maxObservers = 5,
epochZeroStartTimestamp = 0,
epochZeroStartTimestamp = 1704092400000, -- 2024-01-01T00:00:00.000Z
durationMs = 100,
distributionDelayMs = 15,
rewardPercentage = 0.0025, -- 0.25%
Expand Down Expand Up @@ -233,7 +233,8 @@ describe("epochs", function()
it("should throw an error when saving observation too early in the epoch", function()
local observer = "test-this-is-valid-arweave-wallet-address-2"
local reportTxId = "test-this-very-valid-observations-report-tx"
local timestamp = 1
local settings = epochs.getSettings()
local timestamp = settings.epochZeroStartTimestamp + settings.distributionDelayMs - 1
local failedGateways = {
"test-this-is-valid-arweave-wallet-address-1",
}
Expand All @@ -244,7 +245,8 @@ describe("epochs", function()
it("should throw an error if the caller is not prescribed", function()
local observer = "test-this-is-valid-arweave-wallet-address-2"
local reportTxId = "test-this-very-valid-observations-report-tx"
local timestamp = epochs.getSettings().distributionDelayMs + 1
local settings = epochs.getSettings()
local timestamp = settings.epochZeroStartTimestamp + settings.distributionDelayMs + 1
local failedGateways = {
"test-this-is-valid-arweave-wallet-address-1",
}
Expand All @@ -271,7 +273,8 @@ describe("epochs", function()
function()
local observer = "test-this-is-valid-arweave-wallet-address-2"
local reportTxId = "test-this-very-valid-observations-report-tx"
local timestamp = epochs.getSettings().distributionDelayMs + 1
local settings = epochs.getSettings()
local timestamp = settings.epochZeroStartTimestamp + settings.distributionDelayMs + 1
_G.GatewayRegistry = {
["test-this-is-valid-arweave-wallet-address-1"] = {
operatorStake = gar.getSettings().operators.minStake,
Expand Down Expand Up @@ -403,7 +406,7 @@ describe("epochs", function()
describe("getEpochTimestampsForIndex", function()
it("should return the epoch timestamps for the given epoch index", function()
local epochIndex = 0
local expectation = { 0, 100, 115 }
local expectation = { 1704092400000, 1704092400100, 1704092400115 }
local result = { epochs.getEpochTimestampsForIndex(epochIndex) }
assert.are.same(result, expectation)
end)
Expand All @@ -413,11 +416,12 @@ describe("epochs", function()
it(
"should create a new epoch for the given timestamp once distributions for the last epoch have occurred",
function()
local timestamp = 100
local settings = epochs.getSettings()
local epochIndex = 1
local epochStartTimestamp = 100
local epochEndTimestamp = 200
local epochDistributionTimestamp = 215
local epochStartTimestamp = settings.epochZeroStartTimestamp + settings.durationMs
local timestamp = epochStartTimestamp
local epochEndTimestamp = epochStartTimestamp + settings.durationMs
local epochDistributionTimestamp = epochEndTimestamp + settings.distributionDelayMs
local epochStartBlockHeight = 0
local expectation = {
startTimestamp = epochStartTimestamp,
Expand Down
3 changes: 2 additions & 1 deletion src/epochs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,10 @@ function epochs.getEpochTimestampsForIndex(epochIndex)
end

function epochs.getEpochIndexForTimestamp(timestamp)
local timestampInMS = utils.checkAndConvertTimestamptoMs(timestamp)
local epochZeroStartTimestamp = epochs.getSettings().epochZeroStartTimestamp
local epochLengthMs = epochs.getSettings().durationMs
local epochIndex = math.floor((timestamp - epochZeroStartTimestamp) / epochLengthMs)
local epochIndex = math.floor((timestampInMS - epochZeroStartTimestamp) / epochLengthMs)
return epochIndex
end

Expand Down
26 changes: 26 additions & 0 deletions src/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,30 @@ function utils.splitString(str, delimiter)
return result
end

function utils.checkAndConvertTimestamptoMs(timestamp)
-- Check if the timestamp is an integer
if type(timestamp) ~= "number" or timestamp % 1 ~= 0 then
return error("Timestamp must be an integer")
end

-- Define the plausible range for Unix timestamps in seconds
local min_timestamp = 0
local max_timestamp = 4102444800 -- Corresponds to 2100-01-01

if timestamp >= min_timestamp and timestamp <= max_timestamp then
-- The timestamp is already in seconds, convert it to milliseconds
return timestamp * 1000
end

-- If the timestamp is outside the range for seconds, check for milliseconds
local min_timestamp_ms = min_timestamp * 1000
local max_timestamp_ms = max_timestamp * 1000

if timestamp >= min_timestamp_ms and timestamp <= max_timestamp_ms then
return timestamp
end

return error("Timestamp is out of range")
end

return utils

0 comments on commit 434c63f

Please sign in to comment.