Skip to content

Commit

Permalink
feat: add approximate_expiration_time to oracles (#1390)
Browse files Browse the repository at this point in the history
  • Loading branch information
sborrazas committed Jun 13, 2023
1 parent 490d379 commit b008217
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 67 deletions.
32 changes: 32 additions & 0 deletions lib/ae_mdw/db/util.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ defmodule AeMdw.Db.Util do
@typep state() :: State.t()
@typep height() :: Blocks.height()
@typep txi() :: Txs.txi()
@typep time() :: Blocks.time()

@tx_types_to_fname %{
:contract_create_tx => ~w(Chain.clone Chain.create),
:ga_attach_tx => ~w(),
:oracle_response_tx => ~w(Oracle.respond)
}

@approximate_key_block_rate 3 * 60 * 1_000

@spec read_tx!(state(), Txs.txi()) :: Model.tx()
def read_tx!(state, txi), do: State.fetch!(state, Model.Tx, txi)

Expand All @@ -50,6 +53,19 @@ defmodule AeMdw.Db.Util do
end
end

@spec last_gen_and_time(state()) :: {Blocks.height(), Blocks.time()}
def last_gen_and_time(state) do
case State.prev(state, Model.Block, nil) do
{:ok, {height, _mbi}} ->
Model.block(hash: block_hash) = State.fetch!(state, Model.Block, {height, -1})

{height, block_time(block_hash)}

:none ->
raise RuntimeError, message: "can't get last key for table Model.Block"
end
end

@spec block_txi(state(), Blocks.block_index()) :: Txs.txi() | nil
def block_txi(state, bi) do
case State.get(state, Model.Block, bi) do
Expand Down Expand Up @@ -291,4 +307,20 @@ defmodule AeMdw.Db.Util do
tx |> :aect_create_tx.owner_id() |> :aeser_id.specialize(:account)
end
end

@spec height_to_time(state(), height(), height(), time()) :: time()
def height_to_time(state, height, last_height, _last_micro_time) when height <= last_height do
Model.block(hash: block_hash) = State.fetch!(state, Model.Block, {height, -1})

block_time(block_hash)
end

def height_to_time(_state, height, last_height, last_micro_time),
do: last_micro_time + (height - last_height) * @approximate_key_block_rate

defp block_time(block_hash) do
block_hash
|> :aec_db.get_block()
|> :aec_blocks.time_in_msecs()
end
end
15 changes: 9 additions & 6 deletions lib/ae_mdw/oracles.ex
Original file line number Diff line number Diff line change
Expand Up @@ -270,38 +270,38 @@ defmodule AeMdw.Oracles do

@spec fetch(state(), pubkey(), opts()) :: {:ok, oracle()} | {:error, Error.t()}
def fetch(state, oracle_pk, opts) do
last_gen = DBUtil.last_gen(state)
{last_gen, last_time} = DBUtil.last_gen_and_time(state)

case Oracle.locate(state, oracle_pk) do
{m_oracle, source} ->
{:ok, render(state, m_oracle, last_gen, source == Model.ActiveOracle, opts)}
{:ok, render(state, m_oracle, last_gen, last_time, source == Model.ActiveOracle, opts)}

nil ->
{:error, ErrInput.NotFound.exception(value: Enc.encode(:oracle_pubkey, oracle_pk))}
end
end

defp render_list(state, oracles_exp_source_keys, opts) do
last_gen = DBUtil.last_gen(state)
{last_gen, last_time} = DBUtil.last_gen_and_time(state)

Enum.map(oracles_exp_source_keys, fn {{_exp, oracle_pk}, source} ->
is_active? = source == @table_active_expiration

oracle =
State.fetch!(state, if(is_active?, do: @table_active, else: @table_inactive), oracle_pk)

render(state, oracle, last_gen, is_active?, opts)
render(state, oracle, last_gen, last_time, is_active?, opts)
end)
end

defp render_list(state, oracles_exp_keys, is_active?, opts) do
last_gen = DBUtil.last_gen(state)
{last_gen, last_time} = DBUtil.last_gen_and_time(state)

oracles_exp_keys
|> Enum.map(fn {_exp, oracle_pk} ->
State.fetch!(state, if(is_active?, do: @table_active, else: @table_inactive), oracle_pk)
end)
|> Enum.map(&render(state, &1, last_gen, is_active?, opts))
|> Enum.map(&render(state, &1, last_gen, last_time, is_active?, opts))
end

defp render(
Expand All @@ -315,6 +315,7 @@ defmodule AeMdw.Oracles do
previous: _previous
),
last_gen,
last_micro_time,
is_active?,
opts
) do
Expand All @@ -332,6 +333,8 @@ defmodule AeMdw.Oracles do
active: is_active?,
active_from: register_height,
expire_height: expire_height,
approximate_expire_time:
DBUtil.height_to_time(state, expire_height, last_gen, last_micro_time),
register: expand_bi_txi_idx(state, register_bi_txi_idx, opts),
register_tx_hash: Enc.encode(:tx_hash, Txs.txi_to_hash(state, register_txi)),
extends: Enum.map(extends, &expand_bi_txi_idx(state, &1, opts)),
Expand Down
Loading

0 comments on commit b008217

Please sign in to comment.