diff --git a/lib/archethic/reward.ex b/lib/archethic/reward.ex index e084ca6da..92f9c3e0d 100644 --- a/lib/archethic/reward.ex +++ b/lib/archethic/reward.ex @@ -34,7 +34,7 @@ defmodule Archethic.Reward do require Logger @unit_uco 100_000_000 - @number_of_reward_occurences_per_month Utils.number_of_reward_occurences_per_month() + @number_of_occurences_per_month_for_a_year Utils.number_of_possible_reward_occurences_per_month_for_a_year() @doc """ Get rewards amount for validation nodes @@ -53,7 +53,17 @@ defmodule Archethic.Reward do trunc(50 / uco_usd_price / number_of_reward_occurences_per_month * @unit_uco) end - defp number_of_reward_occurences_per_month(), do: @number_of_reward_occurences_per_month + defp number_of_reward_occurences_per_month() do + datetime = NaiveDateTime.utc_now() + + key = + case {datetime.month, Date.leap_year?(datetime)} do + {2, true} -> 0 + {month_num, _} -> month_num + end + + Map.get(@number_of_occurences_per_month_for_a_year, key) + end @doc """ Create a transaction for minting new rewards diff --git a/lib/archethic/utils.ex b/lib/archethic/utils.ex index fdb3a6018..023a79252 100644 --- a/lib/archethic/utils.ex +++ b/lib/archethic/utils.ex @@ -810,6 +810,66 @@ defmodule Archethic.Utils do @doc """ Return the number of occurences for the cron job over the month + ## Examples + + iex> Utils.number_of_possible_reward_occurences_per_month_for_a_year("0 0 2 * * * *") + %{ + 0 => 29, + 1 => 31, + 2 => 28, + 3 => 31, + 4 => 30, + 5 => 31, + 6 => 30, + 7 => 31, + 8 => 31, + 9 => 30, + 10 => 31, + 11 => 30, + 12 => 31 + } + """ + @spec number_of_possible_reward_occurences_per_month_for_a_year(String.t()) :: map + def number_of_possible_reward_occurences_per_month_for_a_year( + interval \\ Application.get_env(:archethic, RewardScheduler)[:interval] + ) do + normal_year = [ + ~N[2023-01-01 00:00:00.000000], + ~N[2023-02-01 00:00:00.000000], + ~N[2023-03-01 00:00:00.000000], + ~N[2023-04-01 00:00:00.000000], + ~N[2023-05-01 00:00:00.000000], + ~N[2023-06-01 00:00:00.000000], + ~N[2023-07-01 00:00:00.000000], + ~N[2023-08-01 00:00:00.000000], + ~N[2023-09-01 00:00:00.000000], + ~N[2023-10-01 00:00:00.000000], + ~N[2023-11-01 00:00:00.000000], + ~N[2023-12-01 00:00:00.000000] + ] + + leap_year_february = ~N[2024-02-01 00:00:00.000000] + + months = normal_year ++ [leap_year_february] + + months + |> Task.async_stream(fn date -> + key = + if Date.leap_year?(date) do + 0 + else + date.month + end + + {key, number_of_reward_occurences_per_month(interval, date)} + end) + |> Stream.map(fn {:ok, v} -> v end) + |> Map.new() + end + + @doc """ + Return the number of occurences for the cron job over the month + ## Examples iex> Utils.number_of_reward_occurences_per_month("0 0 2 * * * *", ~N[2022-11-01 00:00:00.000000]) @@ -818,14 +878,14 @@ defmodule Archethic.Utils do iex> Utils.number_of_reward_occurences_per_month("0 0 2 * * * *", ~N[2022-12-01 00:00:00.000000]) 31 - iex> Utils.number_of_reward_occurences_per_month("0 */5 * * * * *", ~N[2022-11-01 00:00:00.000000]) - 8640 + iex> Utils.number_of_reward_occurences_per_month("0 0 2 * * * *", ~N[2022-02-01 00:00:00.000000]) + 28 + + iex> Utils.number_of_reward_occurences_per_month("0 0 2 * * * *", ~N[2024-02-01 00:00:00.000000]) + 29 """ @spec number_of_reward_occurences_per_month(String.t(), NaiveDateTime.t()) :: non_neg_integer() - def number_of_reward_occurences_per_month( - interval \\ Application.get_env(:archethic, RewardScheduler)[:interval], - current_datetime \\ NaiveDateTime.utc_now() - ) do + def number_of_reward_occurences_per_month(interval, current_datetime) do time = fn true -> " 00:00:00Z" false -> " 23:59:59Z"