Skip to content

Commit

Permalink
feat: add udt hourly statistic
Browse files Browse the repository at this point in the history
  • Loading branch information
rabbitz committed Dec 13, 2024
1 parent 7e63555 commit a9d0deb
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 3 deletions.
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
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
#
54 changes: 54 additions & 0 deletions app/workers/generate_udt_hourly_statistic_worker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
class GenerateUdtHourlyStatisticWorker
include Sidekiq::Job

def perform
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: to_be_counted_date.beginning_of_day.to_i,
}
end

if statistic_attributes.present?
DailyStatisticGenerator.upsert_all(statistic_attributes,
unique_by: %i[udt_id created_at_unixtimestamp])
end
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
1 change: 1 addition & 0 deletions config/routes/v2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,6 @@
resources :graph_nodes, param: :node_id, only: %i[index show]
resources :graph_channels, only: :index
end
resources :udt_hourly_statistics, only: :show
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
79 changes: 76 additions & 3 deletions db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1054,12 +1054,12 @@ ALTER SEQUENCE public.cell_data_cell_output_id_seq OWNED BY public.cell_data.cel

CREATE TABLE public.cell_dependencies (
id bigint NOT NULL,
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 Down Expand Up @@ -2698,6 +2698,41 @@ CREATE SEQUENCE public.udt_holder_allocations_id_seq
ALTER SEQUENCE public.udt_holder_allocations_id_seq OWNED BY public.udt_holder_allocations.id;


--
-- Name: udt_hourly_statistics; Type: TABLE; Schema: public; Owner: -
--

CREATE TABLE public.udt_hourly_statistics (
id bigint NOT NULL,
udt_id bigint NOT NULL,
ckb_transactions_count integer DEFAULT 0,
amount numeric(40,0) DEFAULT 0.0,
holders_count integer DEFAULT 0,
created_at_unixtimestamp integer,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
);


--
-- Name: udt_hourly_statistics_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--

CREATE SEQUENCE public.udt_hourly_statistics_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;


--
-- Name: udt_hourly_statistics_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--

ALTER SEQUENCE public.udt_hourly_statistics_id_seq OWNED BY public.udt_hourly_statistics.id;


--
-- Name: udt_transactions; Type: TABLE; Schema: public; Owner: -
--
Expand Down Expand Up @@ -3364,6 +3399,13 @@ ALTER TABLE ONLY public.udt_accounts ALTER COLUMN id SET DEFAULT nextval('public
ALTER TABLE ONLY public.udt_holder_allocations ALTER COLUMN id SET DEFAULT nextval('public.udt_holder_allocations_id_seq'::regclass);


--
-- Name: udt_hourly_statistics id; Type: DEFAULT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.udt_hourly_statistics ALTER COLUMN id SET DEFAULT nextval('public.udt_hourly_statistics_id_seq'::regclass);


--
-- Name: udt_verifications id; Type: DEFAULT; Schema: public; Owner: -
--
Expand Down Expand Up @@ -3950,6 +3992,14 @@ ALTER TABLE ONLY public.udt_holder_allocations
ADD CONSTRAINT udt_holder_allocations_pkey PRIMARY KEY (id);


--
-- Name: udt_hourly_statistics udt_hourly_statistics_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.udt_hourly_statistics
ADD CONSTRAINT udt_hourly_statistics_pkey PRIMARY KEY (id);


--
-- Name: udt_verifications udt_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
Expand Down Expand Up @@ -4792,6 +4842,20 @@ CREATE INDEX index_cell_dependencies_on_block_number_and_tx_index ON public.cell
CREATE INDEX index_cell_dependencies_on_contract_analyzed ON public.cell_dependencies USING btree (contract_analyzed);


--
-- Name: index_cell_dependencies_on_contract_id; Type: INDEX; Schema: public; Owner: -
--

CREATE INDEX index_cell_dependencies_on_contract_id ON public.cell_dependencies USING btree (contract_id);


--
-- Name: index_cell_dependencies_on_script_id; Type: INDEX; Schema: public; Owner: -
--

CREATE INDEX index_cell_dependencies_on_script_id ON public.cell_dependencies USING btree (script_id);


--
-- Name: index_cell_dependencies_on_tx_id_and_cell_id_and_dep_type; Type: INDEX; Schema: public; Owner: -
--
Expand Down Expand Up @@ -5044,6 +5108,13 @@ CREATE UNIQUE INDEX index_omiga_inscription_infos_on_udt_hash ON public.omiga_in
CREATE INDEX index_on_cell_dependencies_contract_cell_block_tx ON public.cell_dependencies USING btree (contract_cell_id, block_number DESC, tx_index DESC);


--
-- Name: index_on_udt_id_and_unixtimestamp; Type: INDEX; Schema: public; Owner: -
--

CREATE UNIQUE INDEX index_on_udt_id_and_unixtimestamp ON public.udt_hourly_statistics USING btree (udt_id, created_at_unixtimestamp);


--
-- Name: index_portfolios_on_user_id_and_address_id; Type: INDEX; Schema: public; Owner: -
--
Expand Down Expand Up @@ -6127,6 +6198,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20240918033146'),
('20240920094807'),
('20240924065539'),
('20241009081935'),
('20241012014906'),
('20241023055256'),
('20241023063536'),
Expand All @@ -6141,6 +6213,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20241129000339'),
('20241129032447'),
('20241202072604'),
('20241205023729');
('20241205023729'),
('20241212022531');


4 changes: 4 additions & 0 deletions lib/scheduler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,8 @@ def call_worker(clz)
call_worker FiberGraphDetectWorker
end

s.cron "0 8 * * *" do
call_worker GenerateUdtHourlyStatisticWorker
end

s.join

0 comments on commit a9d0deb

Please sign in to comment.