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 all 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
21 changes: 21 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,21 @@
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|
{
xudt_count: statistic.xudt_count.to_s,
dob_count: statistic.dob_count.to_s,
created_at_unixtimestamp: statistic.created_at_unixtimestamp.to_s,
}
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.to_s,
amount: statistic.amount.to_s,
holders_count: statistic.holders_count.to_s,
created_at_unixtimestamp: statistic.created_at_unixtimestamp.to_s,
}
end,
}
end
end
end
end
6 changes: 4 additions & 2 deletions app/models/cell_dependency.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ def to_raw
# Table name: cell_dependencies
#
# id :bigint not null, primary key
# contract_id :bigint
# ckb_transaction_id :bigint not null
# dep_type :integer
# contract_cell_id :bigint not null
# script_id :bigint
# contract_id :bigint
# implicit :boolean
# implicit :boolean default(TRUE), not null
# block_number :bigint
# tx_index :integer
# contract_analyzed :boolean default(FALSE)
Expand All @@ -40,6 +40,8 @@ def to_raw
#
# index_cell_dependencies_on_block_number_and_tx_index (block_number,tx_index)
# index_cell_dependencies_on_contract_analyzed (contract_analyzed)
# index_cell_dependencies_on_contract_id (contract_id)
# index_cell_dependencies_on_script_id (script_id)
# index_cell_dependencies_on_tx_id_and_cell_id_and_dep_type (ckb_transaction_id,contract_cell_id,dep_type) UNIQUE
# index_on_cell_dependencies_contract_cell_block_tx (contract_cell_id,block_number DESC,tx_index DESC)
#
18 changes: 18 additions & 0 deletions app/models/rgbpp_hourly_statistic.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class RgbppHourlyStatistic < ApplicationRecord
end

# == Schema Information
#
# Table name: rgbpp_hourly_statistics
#
# id :bigint not null, primary key
# xudt_count :integer default(0)
# dob_count :integer default(0)
# created_at_unixtimestamp :integer
# created_at :datetime not null
# updated_at :datetime not null
#
# 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
#
26 changes: 26 additions & 0 deletions app/workers/generate_rgbpp_hourly_statistic_worker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class GenerateRgbppHourlyStatisticWorker
include Sidekiq::Job

def perform
xudt_count = Udt.published_xudt.joins(:xudt_tag).where("xudt_tags.tags && ARRAY[?]::varchar[]", ["rgb++"]).count
dob_count = TokenCollection.where("tags && ARRAY[?]::varchar[]", ["rgb++"]).count
created_at_unixtimestamp = to_be_counted_date.beginning_of_day.to_i
RgbppHourlyStatistic.upsert(
{ xudt_count:, dob_count:, created_at_unixtimestamp: },
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
63 changes: 63 additions & 0 deletions app/workers/generate_udt_hourly_statistic_worker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
class GenerateUdtHourlyStatisticWorker
include Sidekiq::Job

def perform(datetime = nil)
ActiveRecord::Base.connection.execute("SET statement_timeout = 0")
start_time = to_be_counted_date(datetime)
generate_statistics(start_time)
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(datetime)
last_record = UdtHourlyStatistic.order(created_at_unixtimestamp: :desc).first
if last_record
Time.zone.at(last_record.created_at_unixtimestamp) + 1.day
else
datetime.is_a?(String) ? Time.zone.parse(datetime) : Time.current.yesterday
end
end

def generate_statistics(start_time)
puts "Generating udt hourly statistics for #{start_time}"
statistic_attributes = []
udt_types = %i[xudt xudt_compatible spore_cell did_cell]
Udt.where(udt_type: udt_types, published: true).find_each do |udt|
statistic_attributes << {
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: start_time.beginning_of_day.to_i,
}
end

if statistic_attributes.present?
UdtHourlyStatistic.upsert_all(statistic_attributes, unique_by: %i[udt_id created_at_unixtimestamp])
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(5000) do |ids|
batch_inputs_amount = CellOutput.select(:udt_amount).where(consumed_by_id: ids).map(&:udt_amount).compact
inputs_amount += batch_inputs_amount.sum
batch_outputs_amount = CellOutput.select(:udt_amount).where(ckb_transaction_id: ids).map(&:udt_amount).compact
outputs_amount += batch_outputs_amount.sum
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
12 changes: 12 additions & 0 deletions db/migrate/20241213053309_create_rgbpp_hourly_statistics.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class CreateRgbppHourlyStatistics < ActiveRecord::Migration[7.0]
def change
create_table :rgbpp_hourly_statistics do |t|
t.integer :xudt_count, default: 0
t.integer :dob_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