-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: index miners count and total rewards from fees (#854)
* feat: index miners count and total rewards from fees Includes a migration that takes 15-30mins to index the already processed generation miners. * refactor: only track miner beneficiaries The reason for this is that miner's pks always change, so for every new key block there will almost always be a new miner. * test: add tests for Stats global values * refactor: move Miners code to private functions
- Loading branch information
Showing
11 changed files
with
320 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
defmodule AeMdw.Db.MinerRewardsMutation do | ||
@moduledoc """ | ||
Adds reward given to a miner and increases the miners count. | ||
""" | ||
|
||
alias AeMdw.Db.IntTransfer | ||
alias AeMdw.Db.State | ||
alias AeMdw.Db.Model | ||
alias AeMdw.Stats | ||
|
||
require Model | ||
|
||
@derive AeMdw.Db.Mutation | ||
defstruct [:rewards] | ||
|
||
@opaque t() :: %__MODULE__{rewards: IntTransfer.rewards()} | ||
|
||
@spec new(IntTransfer.rewards()) :: t() | ||
def new(rewards), do: %__MODULE__{rewards: rewards} | ||
|
||
@spec execute(t(), State.t()) :: State.t() | ||
def execute(%__MODULE__{rewards: rewards}, state) do | ||
Enum.reduce(rewards, state, fn {beneficiary_pk, reward}, state -> | ||
{state, new_miner?} = increment_total_reward(state, beneficiary_pk, reward) | ||
|
||
if new_miner? do | ||
increment_miners_count(state) | ||
else | ||
state | ||
end | ||
end) | ||
end | ||
|
||
defp increment_total_reward(state, beneficiary_pk, reward) do | ||
case State.get(state, Model.Miner, beneficiary_pk) do | ||
{:ok, Model.miner(total_reward: old_reward) = miner} -> | ||
{State.put(state, Model.Miner, Model.miner(miner, total_reward: old_reward + reward)), | ||
false} | ||
|
||
:not_found -> | ||
{State.put( | ||
state, | ||
Model.Miner, | ||
Model.miner(index: beneficiary_pk, total_reward: reward) | ||
), true} | ||
end | ||
end | ||
|
||
defp increment_miners_count(state) do | ||
key = Stats.miners_count_key() | ||
|
||
State.update( | ||
state, | ||
Model.Stat, | ||
key, | ||
fn | ||
Model.stat(payload: count) = stat -> Model.stat(stat, payload: count + 1) | ||
end, | ||
Model.stat(index: key, payload: 0) | ||
) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
defmodule AeMdw.Miners do | ||
@moduledoc """ | ||
Context module for dealing with Miners. | ||
""" | ||
|
||
alias :aeser_api_encoder, as: Enc | ||
alias AeMdw.Collection | ||
alias AeMdw.Db.Model | ||
alias AeMdw.Db.State | ||
alias AeMdw.Node.Db | ||
|
||
require Model | ||
|
||
@type miner() :: map() | ||
@type cursor() :: binary() | nil | ||
@typep state() :: State.t() | ||
@typep pubkey() :: Db.pubkey() | ||
@typep pagination() :: Collection.direction_limit() | ||
|
||
@spec fetch_miners(state(), pagination(), cursor()) :: {cursor(), [miner()], cursor()} | ||
def fetch_miners(state, pagination, cursor) do | ||
cursor = deserialize_cursor(cursor) | ||
|
||
{prev_cursor, miners, next_cursor} = | ||
state | ||
|> build_streamer(cursor) | ||
|> Collection.paginate(pagination) | ||
|
||
{serialize_cursor(prev_cursor), Enum.map(miners, &fetch_miner!(state, &1)), | ||
serialize_cursor(next_cursor)} | ||
end | ||
|
||
@spec fetch_miner!(state(), pubkey()) :: miner() | ||
def fetch_miner!(state, miner_pk), | ||
do: render_miner(State.fetch!(state, Model.Miner, miner_pk)) | ||
|
||
defp build_streamer(state, cursor), do: &Collection.stream(state, Model.Miner, &1, nil, cursor) | ||
|
||
defp render_miner( | ||
Model.miner( | ||
index: miner_pk, | ||
total_reward: total_reward | ||
) | ||
) do | ||
%{ | ||
miner: Enc.encode(:account_pubkey, miner_pk), | ||
total_reward: total_reward | ||
} | ||
end | ||
|
||
defp serialize_cursor(nil), do: nil | ||
|
||
defp serialize_cursor({miner_pk, is_reversed?}), | ||
do: {Enc.encode(:account_pubkey, miner_pk), is_reversed?} | ||
|
||
defp deserialize_cursor(nil), do: nil | ||
|
||
defp deserialize_cursor(cursor_bin) do | ||
case Enc.safe_decode(:account_pubkey, cursor_bin) do | ||
{:ok, miner_pk} -> {:ok, miner_pk} | ||
{:error, _reason} -> nil | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.