-
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: add table with ingoing transactions (#23)
- Loading branch information
1 parent
9c6084f
commit 831d39c
Showing
6 changed files
with
93 additions
and
11 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
78 changes: 78 additions & 0 deletions
78
aggregations/db_tables/daily_ingoing_transactions_per_account_count.py
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,78 @@ | ||
import datetime | ||
|
||
from . import DAY_LEN_SECONDS, daily_start_of_range | ||
from ..periodic_aggregations import PeriodicAggregations | ||
|
||
|
||
class DailyIngoingTransactionsPerAccountCount(PeriodicAggregations): | ||
@property | ||
def sql_create_table(self): | ||
# Suppose we have at most 10^5 (100K) transactions per second. | ||
# In the worst case, they are all from one account. | ||
# It gives ~10^10 transactions per day. | ||
# It means we fit into BIGINT (10^18) | ||
return ''' | ||
CREATE TABLE IF NOT EXISTS daily_ingoing_transactions_per_account_count | ||
( | ||
collected_for_day DATE NOT NULL, | ||
account_id TEXT NOT NULL, | ||
ingoing_transactions_count BIGINT NOT NULL, | ||
CONSTRAINT daily_ingoing_transactions_per_account_count_pk PRIMARY KEY (collected_for_day, account_id) | ||
); | ||
CREATE INDEX IF NOT EXISTS daily_ingoing_transactions_per_account_count_idx | ||
ON daily_ingoing_transactions_per_account_count (collected_for_day, ingoing_transactions_count DESC) | ||
''' | ||
|
||
@property | ||
def sql_drop_table(self): | ||
return ''' | ||
DROP TABLE IF EXISTS daily_ingoing_transactions_per_account_count | ||
''' | ||
|
||
@property | ||
def sql_select(self): | ||
# Ingoing transactions for user X aren't only transactions where receiver_account_id == X. | ||
# We need to find all chains with receipts where X was the receiver. | ||
# It's important to add 10 minutes to receipt border, we should pack the transaction | ||
# with all their receipts together, or the numbers will not be accurate. | ||
# Other receipts from the next day will be naturally ignored. | ||
# Transactions border remains the same, taking only transactions for the specified day. | ||
# If you want to change 10 minutes constant, fix it also in PeriodicAggregations.is_indexer_ready | ||
|
||
# Conditions on receipts timestamps are added because of performance issues: | ||
# Joining 2 relatively small tables work much faster (4-6s VS 70-150s) | ||
# Conditions on transactions timestamps are required by design. | ||
# Though, they were placed into JOIN section also because of performance issues. Not sure why, | ||
# but it changes the query plan to a better one and gives much better performance | ||
return ''' | ||
SELECT | ||
receipts.receiver_account_id, | ||
COUNT(DISTINCT transactions.transaction_hash) AS ingoing_transactions_count | ||
FROM transactions | ||
LEFT JOIN receipts ON receipts.originated_from_transaction_hash = transactions.transaction_hash | ||
AND transactions.block_timestamp >= %(from_timestamp)s | ||
AND transactions.block_timestamp < %(to_timestamp)s | ||
WHERE receipts.included_in_block_timestamp >= %(from_timestamp)s | ||
AND receipts.included_in_block_timestamp < (%(to_timestamp)s + 600000000000) | ||
AND transactions.signer_account_id != receipts.receiver_account_id | ||
GROUP BY receipts.receiver_account_id | ||
''' | ||
|
||
@property | ||
def sql_insert(self): | ||
return ''' | ||
INSERT INTO daily_ingoing_transactions_per_account_count VALUES %s | ||
ON CONFLICT DO NOTHING | ||
''' | ||
|
||
@property | ||
def duration_seconds(self): | ||
return DAY_LEN_SECONDS | ||
|
||
def start_of_range(self, timestamp: int) -> int: | ||
return daily_start_of_range(timestamp) | ||
|
||
@staticmethod | ||
def prepare_data(parameters: list, *, start_of_range=None, **kwargs) -> list: | ||
computed_for = datetime.datetime.utcfromtimestamp(start_of_range).strftime('%Y-%m-%d') | ||
return [(computed_for, account_id, count) for (account_id, count) in parameters] |
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