-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Use trace_replayBlockTransactions API for faster tracing #1543
Conversation
baef3f2
to
5184994
Compare
@goodsoft some chains are exclusively using only |
We can do it like this:
Though, it'll probably be better to split Does this sound adequate to you? |
@goodsoft sounds reasonable |
b9ebdf7
to
1ce1c7d
Compare
Internal transaction fetcher is split into two APIs: * `fetch_block_internal_transactions` is used for Parity * `fetch_internal_transactions` is used for the rest of variants `Indexer.InternalTransaction.Fetcher` is updated to take care of that.
We refetch all internal transactions anyway.
32b8472
to
7f43ad5
Compare
The decrease in coverage is mostly caused by the internal transaction fetching tests being disabled for Geth. While the same code was being used for both Parity and Geth, it was properly exercised, but now Parity has a separate logic. I'll leave it as-is, as figuring out what's up with internal transactions in Geth gets out of the scope of this issue. |
], | ||
http_options: [recv_timeout: :timer.minutes(1), timeout: :timer.minutes(1), hackney: [pool: :ethereum_jsonrpc]] | ||
http_options: [recv_timeout: :timer.minutes(10), timeout: :timer.minutes(10), hackney: [pool: :ethereum_jsonrpc]] |
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.
@goodsoft could you change it also for prod?
json_rpc_named_arguments | ||
|> Keyword.fetch!(:variant) | ||
|> case do | ||
EthereumJSONRPC.Parity -> |
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.
Switching on the variant here seems a little fragile. It might be a good idea to make this an application configuration, so that we could say if Application.get_env(...)
then it becomes a bit more clear. Then the configuration could be placed in the adapter specific configurations like config/parity.exs
.
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 would make sense if both variants supported both APIs, so we could choose one in configuration.
Otherwise, there's exactly one valid value for this setting for each variant and it doesn't make sense to make it configurable at this point.
@goodsoft looks good. but what about my previous comment? |
@ayrat555 if you mean the one about having fallback for Geth, I have implemented it in the second commit. |
Motivation
Currently indexer is using
trace_replayTransaction
JSONRPC method for fetching internal transaction.This caused major slowdown of indexing and forced implementation of ad-hoc elimination rules (e.g. dropping simple token transfers).
Parity supports another API method:
trace_replayBlockTransactions
, which fetches internal transactions for the entire block.Some utterly unscientific tests showed up to 20% speed boost in comparison with current approach, with the added bonus of fetching all transactions, including previously eliminated ones.
Also, previously realtime block fetcher needed to check, whether any particular transaction was a contract, which involved sending multiple
eth_getCode
API requests, which further slowed down new block arrival.Some more unscientific benchmarks showed that employing
trace_replayBlockTransactions
method the average time of a new block arrival into database (inserted_at - timestamp
) went down from ~2m15s to ~0m50s.Changelog
internal_transactions_indexed_at
field to blocks and updateInternalTransactions
import runner to handle it.Chain.stream_transactions_with_unfetched_internal_transactions
withChain.stream_blocks_with_unfetched_internal_transactions
.EthereumJSONRPC.fetch_internal_transactions
to accept list of block numbers and usetrace_replayBlockTransactions
API methodGeth
, as it has a corresponding method, but can't recover association between internal transaction and normal transaction, and has 128 block limit anyway.Upgrading
Migration is added for adding
internal_transactions_indexed_at
toblocks
table.Theoretically, it is possible to update this field with some temporary value for blocks, which only have simple token transfer transactions and already fetched transactions to speed up indexing of interesting transactions, and then reset it back to
nil
for a second pass to index all remaining simple transactions.