Skip to content

Commit

Permalink
perf: remove event hash from log index (#1447)
Browse files Browse the repository at this point in the history
  • Loading branch information
jyeshe committed Jul 6, 2023
1 parent d08ec7e commit d134d72
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 128 deletions.
80 changes: 38 additions & 42 deletions lib/ae_mdw/contracts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ defmodule AeMdw.Contracts do
@pagination_params ~w(limit cursor rev direction scope tx_hash)

@min_fname Util.min_bin()
@min_hash Util.min_bin()
@max_256bit_bin Util.max_256bit_bin()
@max_hash Util.max_256bit_bin()
@min_idx Util.min_int()
@max_idx Util.max_int()
@min_pubkey Util.min_bin()
Expand Down Expand Up @@ -178,21 +176,22 @@ defmodule AeMdw.Contracts do
cursor
) do
key_boundary = {
{data_prefix, first_call_txi, @min_txi, @min_hash, @min_idx},
{data_prefix <> @max_blob, last_call_txi, @max_txi, @max_hash, @max_idx}
{data_prefix, first_call_txi, @min_txi, @min_idx},
{data_prefix <> @max_blob, last_call_txi, @max_txi, @max_idx}
}

cursor =
with {create_txi, call_txi, event_hash, log_idx} = index <- cursor do
Model.contract_log(data: data) = State.fetch!(state, @contract_log_table, index)
{data, call_txi, create_txi, event_hash, log_idx}
with {create_txi, call_txi, log_idx} <- cursor do
key = {create_txi, call_txi, log_idx}
Model.contract_log(data: data) = State.fetch!(state, @contract_log_table, key)
{data, call_txi, create_txi, log_idx}
end

fn direction ->
state
|> Collection.stream(@data_contract_log_table, direction, key_boundary, cursor)
|> Stream.map(fn {_data, call_txi, create_txi, event_hash, log_idx} ->
{create_txi, call_txi, event_hash, log_idx}
|> Stream.map(fn {_data, call_txi, create_txi, log_idx} ->
{create_txi, call_txi, log_idx}
end)
end
end
Expand All @@ -209,80 +208,80 @@ defmodule AeMdw.Contracts do
}

cursor =
with {create_txi, call_txi, event_hash, log_idx} <- cursor do
with {create_txi, call_txi, log_idx} <- cursor do
{event_hash, create_txi, call_txi, log_idx}
end

fn direction ->
state
|> Collection.stream(@ctevt_contract_log_table, direction, key_boundary, cursor)
|> Stream.map(fn {event_hash, create_txi, call_txi, log_idx} ->
{create_txi, call_txi, event_hash, log_idx}
|> Stream.map(fn {_hash, create_txi, call_txi, log_idx} ->
{create_txi, call_txi, log_idx}
end)
end
end

defp build_logs_pagination(
%{create_txi: create_txi},
%{event_hash: event_hash},
state,
{first_call_txi, last_call_txi},
cursor
) do
key_boundary = {
{create_txi, first_call_txi, @min_hash, @min_idx},
{create_txi, last_call_txi, @max_hash, @max_idx}
{event_hash, first_call_txi, @min_txi, @min_idx},
{event_hash, last_call_txi, @max_txi, @max_idx}
}

cursor =
with {create_txi, call_txi, log_idx} <- cursor do
{event_hash, call_txi, create_txi, log_idx}
end

fn direction ->
state
|> Collection.stream(@contract_log_table, direction, key_boundary, cursor)
|> Stream.map(fn {create_txi, call_txi, even_hash, log_idx} ->
{create_txi, call_txi, even_hash, log_idx}
|> Collection.stream(@evt_contract_log_table, direction, key_boundary, cursor)
|> Stream.map(fn {_hash, call_txi, create_txi, log_idx} ->
{create_txi, call_txi, log_idx}
end)
end
end

defp build_logs_pagination(
%{event_hash: event_hash},
%{create_txi: create_txi},
state,
{first_call_txi, last_call_txi},
cursor
) do
key_boundary = {
{event_hash, first_call_txi, @min_txi, @min_idx},
{event_hash, last_call_txi, @max_txi, @max_idx}
{create_txi, first_call_txi, @min_idx},
{create_txi, last_call_txi, @max_idx}
}

cursor =
with {create_txi, call_txi, event_hash, log_idx} <- cursor do
{event_hash, call_txi, create_txi, log_idx}
end

fn direction ->
state
|> Collection.stream(@evt_contract_log_table, direction, key_boundary, cursor)
|> Stream.map(fn {event_hash, call_txi, create_txi, log_idx} ->
{create_txi, call_txi, event_hash, log_idx}
|> Collection.stream(@contract_log_table, direction, key_boundary, cursor)
|> Stream.map(fn {create_txi, call_txi, log_idx} ->
{create_txi, call_txi, log_idx}
end)
end
end

defp build_logs_pagination(_query, state, {first_call_txi, last_call_txi}, cursor) do
key_boundary = {
{first_call_txi, @min_txi, @min_hash, @min_idx},
{last_call_txi, @max_txi, @max_hash, @max_idx}
{first_call_txi, @min_txi, @min_idx},
{last_call_txi, @max_txi, @max_idx}
}

cursor =
with {create_txi, call_txi, event_hash, log_idx} <- cursor do
{call_txi, log_idx, create_txi, event_hash}
with {create_txi, call_txi, log_idx} <- cursor do
{call_txi, log_idx, create_txi}
end

fn direction ->
state
|> Collection.stream(@idx_contract_log_table, direction, key_boundary, cursor)
|> Stream.map(fn {call_txi, log_idx, create_txi, event_hash} ->
{create_txi, call_txi, event_hash, log_idx}
|> Stream.map(fn {call_txi, log_idx, create_txi} ->
{create_txi, call_txi, log_idx}
end)
end
end
Expand Down Expand Up @@ -602,10 +601,8 @@ defmodule AeMdw.Contracts do

defp serialize_logs_cursor(nil), do: nil

defp serialize_logs_cursor({{create_txi, call_txi, event_hash, log_idx}, is_reversed?}) do
event_hash = Base.encode32(event_hash)

{Base.hex_encode32("#{create_txi}$#{call_txi}$#{event_hash}$#{log_idx}",
defp serialize_logs_cursor({{create_txi, call_txi, log_idx}, is_reversed?}) do
{Base.hex_encode32("#{create_txi}$#{call_txi}$#{log_idx}",
padding: false
), is_reversed?}
end
Expand All @@ -614,13 +611,12 @@ defmodule AeMdw.Contracts do

defp deserialize_logs_cursor(cursor_bin) do
with {:ok, decoded_cursor} <- Base.hex_decode32(cursor_bin, padding: false),
[create_txi_bin, call_txi_bin, event_hash_bin, log_idx_bin] <-
[create_txi_bin, call_txi_bin, log_idx_bin] <-
String.split(decoded_cursor, "$"),
{:ok, create_txi} <- deserialize_cursor_int(create_txi_bin),
{:ok, call_txi} <- deserialize_cursor_int(call_txi_bin),
{:ok, event_hash} <- deserialize_cursor_string(event_hash_bin),
{:ok, log_idx} <- deserialize_cursor_int(log_idx_bin) do
{create_txi, call_txi, event_hash, log_idx}
{create_txi, call_txi, log_idx}
else
_invalid_cursor -> nil
end
Expand Down
14 changes: 8 additions & 6 deletions lib/ae_mdw/db/contract.ex
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,17 @@ defmodule AeMdw.Db.Contract do
|> Enum.reduce(state, fn {{addr, [evt_hash | args], data}, log_idx} = log, state ->
m_log =
Model.contract_log(
index: {create_txi, txi, evt_hash, log_idx},
index: {create_txi, txi, log_idx},
ext_contract: (addr != contract_pk && addr) || nil,
args: args,
data: data
data: data,
hash: evt_hash
)

m_data_log = Model.data_contract_log(index: {data, txi, create_txi, evt_hash, log_idx})
m_data_log = Model.data_contract_log(index: {data, txi, create_txi, log_idx})
m_evt_log = Model.evt_contract_log(index: {evt_hash, txi, create_txi, log_idx})
m_ctevt_log = Model.ctevt_contract_log(index: {evt_hash, create_txi, txi, log_idx})
m_idx_log = Model.idx_contract_log(index: {txi, log_idx, create_txi, evt_hash})
m_idx_log = Model.idx_contract_log(index: {txi, log_idx, create_txi})

state2 =
state
Expand Down Expand Up @@ -663,10 +664,11 @@ defmodule AeMdw.Db.Contract do
# on called log: ext_contract = {:parent_contract_pk, caller contract_pk}
m_log_remote =
Model.contract_log(
index: {remote_contract_txi, txi, evt_hash, idx},
index: {remote_contract_txi, txi, idx},
ext_contract: {:parent_contract_pk, contract_pk},
args: args,
data: data
data: data,
hash: evt_hash
)

m_evt_log = Model.evt_contract_log(index: {evt_hash, txi, remote_contract_txi, idx})
Expand Down
29 changes: 16 additions & 13 deletions lib/ae_mdw/db/model.ex
Original file line number Diff line number Diff line change
Expand Up @@ -636,37 +636,40 @@ defmodule AeMdw.Db.Model do
)

# contract log:
# index: {create txi, call txi, event hash, log idx}
# index: {create txi, call txi, log idx}
# ext_contract: nil || ext_contract_pk
# args: []
# data: ""
# args: [topic]
# data: raw log data binary
# event hash: <<_::256>>
@contract_log_defaults [
index: {-1, -1, nil, -1},
index: {-1, -1, -1},
ext_contract: nil,
args: [],
data: ""
data: "",
hash: <<0::256>>
]
defrecord :contract_log, @contract_log_defaults

@type contract_log_index() :: {txi(), txi(), Contract.event_hash(), non_neg_integer()}
@type contract_log_index() :: {txi(), txi(), non_neg_integer()}
@type contract_log() ::
record(:contract_log,
index: contract_log_index(),
ext_contract: pubkey() | nil | {:parent_contract_pk, pubkey()},
args: [term()],
data: DbContract.log_data()
data: DbContract.log_data(),
hash: Contract.event_hash()
)

# data contract log:
# index: {data, call txi, create txi, event hash, log idx}
# index: {data, call txi, create txi, log idx}
@data_contract_log_defaults [
index: {nil, -1, -1, nil, -1},
index: {nil, -1, -1, -1},
unused: nil
]
defrecord :data_contract_log, @data_contract_log_defaults

@type data_contract_log_index() ::
{DbContract.log_data(), txi(), txi(), Contract.event_hash(), non_neg_integer()}
{DbContract.log_data(), txi(), txi(), non_neg_integer()}
@type data_contract_log() :: record(:data_contract_log, index: data_contract_log_index())

# evt contract log:
Expand All @@ -692,14 +695,14 @@ defmodule AeMdw.Db.Model do
@type evt_contract_log() :: record(:evt_contract_log, index: evt_contract_log_index())

# idx contract log:
# index: {call txi, log idx, create_txi, event hash}
# index: {call txi, log idx, create_txi}
@idx_contract_log_defaults [
index: {-1, -1, -1, <<>>},
index: {-1, -1, -1},
unused: nil
]
defrecord :idx_contract_log, @idx_contract_log_defaults

@type idx_contract_log_index() :: {txi(), non_neg_integer(), txi(), Contracts.event_hash()}
@type idx_contract_log_index() :: {txi(), non_neg_integer(), txi()}
@type idx_contract_log() :: record(:idx_contract_log, index: idx_contract_log_index())

# aex9 transfer:
Expand Down
6 changes: 3 additions & 3 deletions lib/ae_mdw_web/views/logs_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ defmodule AeMdwWeb.LogsView do
@type opts :: %{aexn_args: boolean(), custom_args: boolean()}

@spec render_log(State.t(), AeMdw.Contracts.log(), opts()) :: map()
def render_log(state, {create_txi, call_txi, event_hash, log_idx}, encode_args) do
def render_log(state, {create_txi, call_txi, log_idx}, encode_args) do
{contract_tx_hash, ct_pk} =
if create_txi == -1 do
{nil, Origin.pubkey(state, {:contract_call, call_txi})}
Expand All @@ -27,8 +27,8 @@ defmodule AeMdwWeb.LogsView do

Model.block(hash: block_hash) = DBUtil.read_block!(state, {height, micro_index})

Model.contract_log(args: args, data: data, ext_contract: ext_contract) =
State.fetch!(state, Model.ContractLog, {create_txi, call_txi, event_hash, log_idx})
Model.contract_log(args: args, data: data, ext_contract: ext_contract, hash: event_hash) =
State.fetch!(state, Model.ContractLog, {create_txi, call_txi, log_idx})

event_name = AexnContracts.event_name(event_hash) || get_custom_event_name(event_hash)

Expand Down
Loading

0 comments on commit d134d72

Please sign in to comment.