-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: introduce now transaction hash range scoping #2096
Conversation
299c471
to
f6f4ea4
Compare
lib/ae_mdw/txs.ex
Outdated
def tx_hash_to_txi(state, tx_hash) do | ||
encoded_tx_hash = :aeser_api_encoder.encode(:tx_hash, tx_hash) | ||
|
||
with mb_hash when is_binary(mb_hash) <- :aec_db.find_tx_location(tx_hash), | ||
{:ok, mb_height} <- Db.find_block_height(mb_hash) do | ||
state | ||
|> Blocks.fetch_txis_from_gen(mb_height) | ||
|> Stream.map(&State.fetch!(state, @table, &1)) | ||
|> Enum.find_value( | ||
{:error, ErrInput.NotFound.exception(value: encoded_tx_hash)}, | ||
fn | ||
Model.tx(index: txi, id: ^tx_hash) -> {:ok, txi} | ||
_tx -> nil | ||
end | ||
) | ||
else | ||
_no_block_or_header -> | ||
{:error, ErrInput.NotFound.exception(value: encoded_tx_hash)} | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @sborrazas I was looking for the find_tx_location
to catch up with the code again and came across with the fetch/3
. It seems a good opportunity of reuse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what you mean here, you mean fetching the full tx with the rendering by calling fetch/3
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the difference to the fetch/3
, it would be only on the line of the {:ok, txt}
return.
def fetch(state, tx_hash, opts) when is_binary(tx_hash) do
encoded_tx_hash = :aeser_api_encoder.encode(:tx_hash, tx_hash)
with mb_hash when is_binary(mb_hash) <- :aec_db.find_tx_location(tx_hash),
{:ok, mb_height} <- Db.find_block_height(mb_hash) do
state
|> Blocks.fetch_txis_from_gen(mb_height)
|> Stream.map(&State.fetch!(state, @table, &1))
|> Enum.find_value(
{:error, ErrInput.NotFound.exception(value: encoded_tx_hash)},
fn
Model.tx(id: ^tx_hash) = tx -> {:ok, render(state, tx, opts)}
_tx -> nil
end
)
else
_no_block_or_header ->
{:error, ErrInput.NotFound.exception(value: encoded_tx_hash)}
end
end
There would be multiple ways to refactor to reuse most of it in a way that only the rendering varies. Maybe a good reason to decouple the rendering from the fetching or would consider just rendering in another way as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, I extracted it into the function that returns {:ok, Model.tx()}
so it can be reused in both places
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Brilliant!
_txi_scope, | ||
state | ||
) do | ||
with tx_hashes when length(tx_hashes) > 0 and length(tx_hashes) <= 2 <- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an alternative suggest would be to pattern match with [_hash1, _hash2] = tx_hashes
, similar, just another flavour
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't pattern-match on this since it's valid for it to be a single element array too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean this format [_hash1 | _hash2] = tx_hashes
for a more compact condition but it's fine the lengthy one (:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nvm, it would be lengthier checking the rest of the list
end | ||
|
||
defp extract_direction_and_scope( | ||
%{"scope_type" => scope_type} = params, | ||
_txi_scope? = false, | ||
state | ||
) | ||
when scope_type in ["gen", "time", "epoch"] do | ||
when scope_type in ["gen", "time", "epoch", "transaction"] do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔆
{:ok, :backward, {scope_type, last..first}} | ||
end | ||
|
||
defp generate_range(_state, scope_type, first, last, params) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this is the match for first = last
, maybe instead of calling first
and last
just call it smth like gen
?
It made me thinking about it after looking at the
{:ok, :forward, {scope_type, last..first}}
while above we have
{:ok, :forward, {scope_type, first..last}}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not always a gen, it can be txis and I think time too
refs #2075