From 8055a6438ed6c32df3d5f3155bf47da815c5e877 Mon Sep 17 00:00:00 2001 From: Rabbit Date: Mon, 30 Dec 2024 15:04:52 +0800 Subject: [PATCH 1/2] feat: add network to bitcoin statistics --- app/models/bitcoin_statistic.rb | 24 +------ .../generate_bitcoin_statistic_worker.rb | 62 +++++++++++++++++++ ...70841_add_network_to_bitcoin_statistics.rb | 7 +++ db/structure.sql | 2 +- lib/scheduler.rb | 2 +- 5 files changed, 73 insertions(+), 24 deletions(-) create mode 100644 app/workers/generate_bitcoin_statistic_worker.rb create mode 100644 db/migrate/20241229070841_add_network_to_bitcoin_statistics.rb diff --git a/app/models/bitcoin_statistic.rb b/app/models/bitcoin_statistic.rb index 49bae6460..507e58590 100644 --- a/app/models/bitcoin_statistic.rb +++ b/app/models/bitcoin_statistic.rb @@ -1,26 +1,6 @@ class BitcoinStatistic < ApplicationRecord + enum :network, %i[ckb btc] default_scope { order(timestamp: :asc) } - - def self.refresh - transaction do - current_time = Time.current - end_time = Time.zone.local(current_time.year, current_time.month, current_time.day, current_time.hour, current_time.min) - start_time = end_time - 30.minutes - - Rails.logger.info "current_time: #{current_time}, start_time: #{start_time}, end_time: #{end_time}" - - # Count the number of newly generated addresses within half an hour before the current time point - addresses_count = BitcoinAddress.where(created_at: start_time..end_time).count - # Count the number of newly generated transactions within half an hour before the current time point - transactions_count = BitcoinTransaction.where(created_at: start_time..end_time).count - Rails.logger.info "update bitcoin_statistics addresses_count(#{addresses_count}) transactions_count(#{transactions_count})" - - statistic = BitcoinStatistic.find_or_initialize_by(timestamp: end_time.utc.to_i * 1000) - statistic.addresses_count = addresses_count - statistic.transactions_count = transactions_count - statistic.save! - end - end end # == Schema Information @@ -34,5 +14,5 @@ def self.refresh # # Indexes # -# index_bitcoin_statistics_on_timestamp (timestamp) UNIQUE +# index_bitcoin_statistics_on_timestamp (timestamp) # diff --git a/app/workers/generate_bitcoin_statistic_worker.rb b/app/workers/generate_bitcoin_statistic_worker.rb new file mode 100644 index 000000000..8843a7745 --- /dev/null +++ b/app/workers/generate_bitcoin_statistic_worker.rb @@ -0,0 +1,62 @@ +class GenerateBitcoinStatisticWorker + include Sidekiq::Job + sidekiq_options queue: "rgbpp" + + attr_accessor :datetime + + def perform + start_time, end_time = time_range + statistic_attributes = [ + btc_attributes(start_time, end_time), + ckb_attributes(start_time, end_time), + ] + + Rails.logger.info "update bitcoin_statistics #{statistic_attributes}" + + BitcoinStatistic.upsert_all(statistic_attributes, unique_by: %i[timestamp network]) + rescue StandardError => e + Rails.logger.error "Error occurred during GenerateRgbppHourlyStatistic error: #{e.message}" + end + + private + + def btc_attributes(start_time, end_time) + addresses_count = BitcoinAddress.where(created_at: start_time..end_time).count + transactions_count = BitcoinTransaction.where(created_at: start_time..end_time).count + timestamp = end_time.utc.to_i * 1000 + { timestamp:, addresses_count:, transactions_count:, network: :btc } + end + + def ckb_attributes(start_time, end_time) + start_timestamp = CkbUtils.time_in_milliseconds(start_time) + end_timestamp = CkbUtils.time_in_milliseconds(end_time) - 1 + + ft_transaction_ids = Set.new + Udt.where(udt_type: %i[xudt xudt_compatible]).find_each do |xudt| + ft_transaction_ids.merge(xudt.ckb_transactions.where(block_timestamp: start_timestamp..end_timestamp).ids) + end + + dob_transaction_ids = Set.new + TokenCollection.spore.find_each do |token_collection| + transfers = token_collection.transfers.joins(:ckb_transaction). + where("ckb_transactions.block_timestamp >= ?", start_timestamp). + where("ckb_transactions.block_timestamp < ?", end_timestamp) + + dob_transaction_ids.merge(transfers.map(&:transaction_id)) + end + + transactions_count = ft_transaction_ids.length + dob_transaction_ids.length + timestamp = end_time.utc.to_i * 1000 + { timestamp:, transactions_count:, network: :ckb } + end + + def time_range + current_time = Time.current + end_time = Time.zone.local(current_time.year, current_time.month, current_time.day, current_time.hour, current_time.min) + start_time = end_time - 30.minutes + + Rails.logger.info "current_time: #{current_time}, start_time: #{start_time}, end_time: #{end_time}" + + [start_time, end_time] + end +end diff --git a/db/migrate/20241229070841_add_network_to_bitcoin_statistics.rb b/db/migrate/20241229070841_add_network_to_bitcoin_statistics.rb new file mode 100644 index 000000000..8016bd52d --- /dev/null +++ b/db/migrate/20241229070841_add_network_to_bitcoin_statistics.rb @@ -0,0 +1,7 @@ +class AddNetworkToBitcoinStatistics < ActiveRecord::Migration[7.0] + def change + add_column :bitcoin_statistics, :network, :integer, default: :btc + remove_index :bitcoin_statistics, :timestamp + add_index :bitcoin_statistics, %i[timestamp network], unique: true + end +end diff --git a/db/structure.sql b/db/structure.sql index 1b35e256c..674ec9e60 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -4771,7 +4771,7 @@ CREATE UNIQUE INDEX index_bitcoin_annotations_on_ckb_transaction_id ON public.bi -- Name: index_bitcoin_statistics_on_timestamp; Type: INDEX; Schema: public; Owner: - -- -CREATE UNIQUE INDEX index_bitcoin_statistics_on_timestamp ON public.bitcoin_statistics USING btree ("timestamp"); +CREATE INDEX index_bitcoin_statistics_on_timestamp ON public.bitcoin_statistics USING btree ("timestamp"); -- diff --git a/lib/scheduler.rb b/lib/scheduler.rb index b9006f311..6cae16510 100644 --- a/lib/scheduler.rb +++ b/lib/scheduler.rb @@ -115,7 +115,7 @@ def call_worker(clz) end s.cron "0,30 * * * *" do - BitcoinStatistic.refresh + call_worker GenerateBitcoinStatisticWorker end s.every "2m", overlap: false do From 694447140de7dac55963f779a90e5f9a72e40555 Mon Sep 17 00:00:00 2001 From: Rabbit Date: Mon, 30 Dec 2024 15:45:29 +0800 Subject: [PATCH 2/2] chore: update bitcoin statistics log --- app/workers/generate_bitcoin_statistic_worker.rb | 4 ++-- .../20241229070841_add_network_to_bitcoin_statistics.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/workers/generate_bitcoin_statistic_worker.rb b/app/workers/generate_bitcoin_statistic_worker.rb index 8843a7745..37b41e7fe 100644 --- a/app/workers/generate_bitcoin_statistic_worker.rb +++ b/app/workers/generate_bitcoin_statistic_worker.rb @@ -15,7 +15,7 @@ def perform BitcoinStatistic.upsert_all(statistic_attributes, unique_by: %i[timestamp network]) rescue StandardError => e - Rails.logger.error "Error occurred during GenerateRgbppHourlyStatistic error: #{e.message}" + Rails.logger.error "Error occurred during GenerateBitcoinStatisticWorker error: #{e.message}" end private @@ -47,7 +47,7 @@ def ckb_attributes(start_time, end_time) transactions_count = ft_transaction_ids.length + dob_transaction_ids.length timestamp = end_time.utc.to_i * 1000 - { timestamp:, transactions_count:, network: :ckb } + { timestamp:, addresses_count: 0, transactions_count:, network: :ckb } end def time_range diff --git a/db/migrate/20241229070841_add_network_to_bitcoin_statistics.rb b/db/migrate/20241229070841_add_network_to_bitcoin_statistics.rb index 8016bd52d..00b293ff2 100644 --- a/db/migrate/20241229070841_add_network_to_bitcoin_statistics.rb +++ b/db/migrate/20241229070841_add_network_to_bitcoin_statistics.rb @@ -1,6 +1,6 @@ class AddNetworkToBitcoinStatistics < ActiveRecord::Migration[7.0] def change - add_column :bitcoin_statistics, :network, :integer, default: :btc + add_column :bitcoin_statistics, :network, :integer remove_index :bitcoin_statistics, :timestamp add_index :bitcoin_statistics, %i[timestamp network], unique: true end