Skip to content
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

eIssue 256 #2341

Merged
merged 8 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions app/controllers/api/v2/rgbpp_hourly_statistics_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module Api
module V2
class RgbppHourlyStatisticsController < BaseController
def index
expires_in 15.minutes, public: true, stale_while_revalidate: 5.minutes, stale_if_error: 5.minutes

rgbpp_statistics = RgbppHourlyStatistic.order(created_at_unixtimestamp: :asc)

render json: {
data: rgbpp_statistics.map do |statistic|
{
total_count: statistic.total_count,
created_at_unixtimestamp: statistic.created_at_unixtimestamp,
}
end,
}
end
end
end
end
28 changes: 28 additions & 0 deletions app/controllers/api/v2/udt_hourly_statistics_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module Api
module V2
class UdtHourlyStatisticsController < BaseController
def show
expires_in 15.minutes, public: true, stale_while_revalidate: 5.minutes, stale_if_error: 5.minutes

udt = Udt.find_by!(type_hash: params[:id], published: true)
hourly_statistics =
if udt.present?
UdtHourlyStatistic.where(udt:).order(created_at_unixtimestamp: :asc)
else
UdtHourlyStatistic.none
end

render json: {
data: hourly_statistics.map do |statistic|
{
ckb_transactions_count: statistic.ckb_transactions_count,
amount: statistic.amount,
holders_count: statistic.holders_count,
created_at_unixtimestamp: statistic.created_at_unixtimestamp,
}
end,
}
end
end
end
end
17 changes: 17 additions & 0 deletions app/models/rgbpp_hourly_statistic.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class RgbppHourlyStatistic < ApplicationRecord
end

# == Schema Information
#
# Table name: rgbpp_hourly_statistics
#
# id :bigint not null, primary key
# total_count :integer default(0)
# created_at_unixtimestamp :integer
# created_at :datetime not null
# updated_at :datetime not null
rabbitz marked this conversation as resolved.
Show resolved Hide resolved
#
# Indexes
#
# index_rgbpp_hourly_statistics_on_created_at_unixtimestamp (created_at_unixtimestamp) UNIQUE
#
40 changes: 40 additions & 0 deletions app/models/udt_hourly_statistic.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class UdtHourlyStatistic < ApplicationRecord
belongs_to :udt

def percentage_change(attribute)
yesterday = previous_stat(udt_id, 1)
day_before_yesterday = previous_stat(udt_id, 2)

return nil unless yesterday && day_before_yesterday

yesterday_value = yesterday.public_send(attribute)
day_before_yesterday_value = day_before_yesterday.public_send(attribute)

return nil if day_before_yesterday_value.zero?

((yesterday_value - day_before_yesterday_value).to_f / day_before_yesterday_value * 100).round(2)
end

def previous_stat(udt_id, days_ago)
timestamp = (Time.current - days_ago.days).beginning_of_day.to_i
self.class.find_by(udt_id:, created_at_unixtimestamp: timestamp)
end
end

# == Schema Information
#
# Table name: udt_hourly_statistics
#
# id :bigint not null, primary key
# udt_id :bigint not null
# ckb_transactions_count :integer default(0)
# amount :decimal(40, ) default(0)
# holders_count :integer default(0)
# created_at_unixtimestamp :integer
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_on_udt_id_and_unixtimestamp (udt_id,created_at_unixtimestamp) UNIQUE
#
28 changes: 28 additions & 0 deletions app/workers/generate_rgbpp_hourly_statistic_worker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class GenerateRgbppHourlyStatisticWorker
include Sidekiq::Job

def perform
xudts_count = Udt.published_xudt.joins(:xudt_tag).where("xudt_tags.tags && ARRAY[?]::varchar[]", ["rgb++"]).count
nft_collections_count = TokenCollection.where("tags && ARRAY[?]::varchar[]", ["rgb++"]).count
RgbppHourlyStatistic.upsert(
{
total_count: xudts_count + nft_collections_count,
created_at_unixtimestamp: to_be_counted_date.beginning_of_day.to_i,
},
unique_by: :created_at_unixtimestamp,
)
rescue StandardError => e
Rails.logger.error "Error occurred during GenerateRgbppHourlyStatistic error: #{e.message}"
end

private

def to_be_counted_date
last_record = UdtHourlyStatistic.order(created_at_unixtimestamp: :desc).first
if last_record
Time.zone.at(last_record.created_at_unixtimestamp) + 1.day
else
Time.current.yesterday
end
end
end
55 changes: 55 additions & 0 deletions app/workers/generate_udt_hourly_statistic_worker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
class GenerateUdtHourlyStatisticWorker
include Sidekiq::Job

def perform
udt_types = %i[xudt xudt_compatible spore_cell did_cell]
created_at_unixtimestamp = to_be_counted_date.beginning_of_day.to_i
ActiveRecord::Base.connection.execute("SET statement_timeout = 0")
Udt.where(udt_type: udt_types, published: true).find_each do |udt|
puts "Generating statistics for #{udt.id}"
RgbppHourlyStatistic.upsert(
{
udt_id: udt.id,
amount: calc_amount(udt),
ckb_transactions_count: calc_ckb_transactions_count(udt),
holders_count: calc_holders_count(udt),
created_at_unixtimestamp:,
},
unique_by: %i[udt_id created_at_unixtimestamp],
)
end
ActiveRecord::Base.connection.execute("RESET statement_timeout")
rescue StandardError => e
Rails.logger.error "Error occurred during GenerateUdtHourlyStatistic error: #{e.message}"
end

private

def to_be_counted_date
last_record = UdtHourlyStatistic.order(created_at_unixtimestamp: :desc).first
if last_record
Time.zone.at(last_record.created_at_unixtimestamp) + 1.day
else
Time.current.yesterday
end
end

def calc_amount(udt)
inputs_amount = 0
outputs_amount = 0
ckb_transaction_ids = udt.ckb_transactions.map(&:id)
ckb_transaction_ids.each_slice(1000) do |ids|
inputs_amount += CellOutput.where(consumed_by_id: ids).sum(:udt_amount)
outputs_amount += CellOutput.where(ckb_transaction_id: ids).sum(:udt_amount)
end
[inputs_amount, outputs_amount].max
end

def calc_ckb_transactions_count(udt)
udt.ckb_transactions.count
end

def calc_holders_count(udt)
udt.udt_holder_allocations.sum("ckb_holder_count + btc_holder_count")
end
end
2 changes: 2 additions & 0 deletions config/routes/v2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,7 @@
resources :graph_nodes, param: :node_id, only: %i[index show]
resources :graph_channels, only: :index
end
resources :udt_hourly_statistics, only: :show
resources :rgbpp_hourly_statistics, only: :index
end
end
14 changes: 14 additions & 0 deletions db/migrate/20241212022531_create_udt_hourly_statistics.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class CreateUdtHourlyStatistics < ActiveRecord::Migration[7.0]
def change
create_table :udt_hourly_statistics do |t|
t.bigint :udt_id, null: false
t.integer :ckb_transactions_count, default: 0
t.decimal :amount, precision: 40, default: 0.0
t.integer :holders_count, default: 0
t.integer :created_at_unixtimestamp
t.timestamps
end

add_index :udt_hourly_statistics, %i[udt_id created_at_unixtimestamp], name: "index_on_udt_id_and_unixtimestamp", unique: true
end
end
11 changes: 11 additions & 0 deletions db/migrate/20241213053309_create_rgbpp_hourly_statistics.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreateRgbppHourlyStatistics < ActiveRecord::Migration[7.0]
def change
create_table :rgbpp_hourly_statistics do |t|
t.integer :total_count, default: 0
t.integer :created_at_unixtimestamp
t.timestamps
end

add_index :rgbpp_hourly_statistics, :created_at_unixtimestamp, unique: true
end
end
Loading
Loading