Skip to content

Commit 77b5678

Browse files
authored
Merge pull request #2496 from nervosnetwork/testnet
Deploy to mainnet
2 parents 90aea3a + 9b05e87 commit 77b5678

File tree

9 files changed

+555
-49
lines changed

9 files changed

+555
-49
lines changed

.rubocop.yml

Lines changed: 401 additions & 0 deletions
Large diffs are not rendered by default.

app/controllers/api/v2/fiber/statistics_controller.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,7 @@ def index
66
expires_in 15.minutes, public: true, stale_while_revalidate: 5.minutes, stale_if_error: 5.minutes
77
statistics = FiberStatistic.order(created_at_unixtimestamp: :desc).limit(7)
88

9-
render json: {
10-
data: statistics.map do |statistic|
11-
statistic.attributes.except("id", "created_at", "updated_at").transform_values(&:to_s)
12-
end,
13-
}
9+
render json: { data: statistics.map(&:as_json) }
1410
end
1511

1612
def show

app/models/ckb_sync/new_node_data_processor.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class NewNodeDataProcessor
1010
value :reorg_started_at, global: true
1111
attr_accessor :local_tip_block, :pending_raw_block, :ckb_txs, :target_block, :target_block_number, :addrs_changes,
1212
:outputs, :inputs, :outputs_data, :udt_address_ids, :contained_address_ids,
13-
:contained_udt_ids, :cell_datas, :enable_cota, :token_transfer_ckb_tx_ids
13+
:contained_udt_ids, :cell_datas, :enable_cota, :token_transfer_ckb_tx_ids, :addr_tx_changes
1414

1515
def initialize(enable_cota = ENV["COTA_AGGREGATOR_URL"].present?)
1616
@enable_cota = enable_cota
@@ -72,6 +72,7 @@ def process_block(node_block, refresh_balance: true)
7272
benchmark :process_ckb_txs, node_block, ckb_txs, contained_address_ids,
7373
contained_udt_ids, tags, udt_address_ids
7474
@addrs_changes = Hash.new { |hash, key| hash[key] = {} }
75+
@addr_tx_changes = Hash.new { |h, k| h[k] = Hash.new(0) }
7576

7677
input_capacities, output_capacities = benchmark :build_cells_and_locks!, local_block, node_block, ckb_txs, inputs, outputs,
7778
tags, udt_address_ids, contained_udt_ids, contained_address_ids, addrs_changes, token_transfer_ckb_tx_ids, cell_deps
@@ -526,7 +527,7 @@ def update_addresses_info(addrs_change, local_block, refresh_balance)
526527
ckb_transactions_count: addr.ckb_transactions_count,
527528
live_cells_count: addr.live_cells_count,
528529
dao_transactions_count: addr.dao_transactions_count,
529-
last_updated_block_number: local_block.number
530+
last_updated_block_number: local_block.number,
530531
},
531532
address_id: addr.id,
532533
block_id: local_block.id,
@@ -688,7 +689,7 @@ def update_ckb_txs_rel_and_fee(
688689
tx_id = tx["id"]
689690
full_tx_address_ids +=
690691
contained_addr_ids[tx_index].to_a.map do |address_id|
691-
{ address_id:, ckb_transaction_id: tx_id, income: addrs_changes[address_id][:balance_diff], block_number: target_block_number, tx_index: }
692+
{ address_id:, ckb_transaction_id: tx_id, income: addr_tx_changes[tx_index][address_id], block_number: target_block_number, tx_index: }
692693
end
693694
full_tx_udt_ids += contained_udt_ids[tx_index].to_a.map do |u|
694695
{ udt_id: u, ckb_transaction_id: tx_id }
@@ -931,8 +932,8 @@ def build_cell_inputs(
931932
type_hash = attributes[:type_hash]
932933
data = attributes[:data]
933934
change_rec = addrs_changes[address_id]
934-
# change_rec.with_defaults!
935935

936+
addr_tx_changes[tx_index][address_id] -= capacity
936937
change_rec[:balance_diff] ||= 0
937938
change_rec[:balance_diff] -= capacity
938939
change_rec[:balance_occupied_diff] ||= 0
@@ -1005,6 +1006,7 @@ def build_cell_outputs!(
10051006
address_id = address.id
10061007
cell_data = node_block.transactions[tx_index].outputs_data[cell_index]
10071008
change_rec = addrs_changes[address_id]
1009+
addr_tx_changes[tx_index][address_id] += item.capacity
10081010

10091011
change_rec[:balance_diff] ||= 0
10101012
change_rec[:balance_diff] += item.capacity

app/models/fiber_graph_channel.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,12 @@ def deleted_at_timestamp
7676
# fee_rate_of_node1 :decimal(30, ) default(0)
7777
# fee_rate_of_node2 :decimal(30, ) default(0)
7878
# deleted_at :datetime
79+
# cell_output_id :bigint
80+
# address_id :bigint
7981
#
8082
# Indexes
8183
#
84+
# index_fiber_graph_channels_on_address_id (address_id)
8285
# index_fiber_graph_channels_on_channel_outpoint (channel_outpoint) UNIQUE
8386
# index_fiber_graph_channels_on_deleted_at (deleted_at)
8487
#

app/models/fiber_statistic.rb

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,100 @@
11
class FiberStatistic < ApplicationRecord
2-
VALID_INDICATORS = %w(total_nodes total_channels total_liquidity created_at_unixtimestamp).freeze
2+
include AttrLogics
3+
4+
VALID_INDICATORS = %w(total_nodes total_channels total_capacity created_at_unixtimestamp).freeze
35

46
scope :filter_by_indicator, ->(indicator) {
57
raise ArgumentError, "Invalid indicator" unless VALID_INDICATORS.include?(indicator.to_s)
68

79
select(indicator, :created_at_unixtimestamp)
810
}
11+
12+
define_logic(:total_nodes) { FiberGraphNode.count }
13+
define_logic(:total_channels) { FiberGraphChannel.count }
14+
define_logic(:total_capacity) { FiberGraphChannel.sum(:capacity) }
15+
16+
define_logic :total_liquidity do
17+
result = Hash.new { |h, k| h[k] = 0.0 }
18+
19+
FiberGraphNode.find_each do |node|
20+
channels = FiberGraphChannel.with_deleted.where(node1: node.node_id).or(
21+
FiberGraphChannel.with_deleted.where(node2: node.node_id),
22+
).where(closed_transaction_id: nil)
23+
24+
channels.each do |channel|
25+
funding_cell = channel.funding_cell
26+
if funding_cell.cell_type.in?(%w(udt xudt xudt_compatible))
27+
result[funding_cell.type_hash] += funding_cell.udt_amount
28+
else
29+
result[""] += channel.capacity
30+
end
31+
end
32+
end
33+
34+
CkbUtils.hash_value_to_s(result)
35+
end
36+
37+
define_logic :mean_value_locked do
38+
total_channels.zero? ? 0.0 : total_capacity.to_f / total_channels
39+
end
40+
41+
define_logic :mean_fee_rate do
42+
FiberGraphChannel.average("fee_rate_of_node1 + fee_rate_of_node2") || 0.0
43+
end
44+
45+
define_logic :medium_value_locked do
46+
capacities = FiberGraphChannel.pluck(:capacity).compact
47+
calculate_median(capacities)
48+
end
49+
50+
define_logic :medium_fee_rate do
51+
fee_rate_of_node1 = FiberGraphChannel.pluck(:fee_rate_of_node1).compact
52+
fee_rate_of_node2 = FiberGraphChannel.pluck(:fee_rate_of_node2).compact
53+
combined_fee_rates = fee_rate_of_node1 + fee_rate_of_node2
54+
calculate_median(combined_fee_rates)
55+
end
56+
57+
def calculate_median(array)
58+
sorted = array.sort
59+
count = sorted.size
60+
return nil if count.zero?
61+
62+
if count.odd?
63+
sorted[count / 2]
64+
else
65+
(sorted[(count / 2) - 1] + sorted[count / 2]).to_f / 2
66+
end
67+
end
68+
69+
def parsed_total_liquidity
70+
total_liquidity&.map do |type_hash, amount|
71+
if type_hash.present?
72+
udt_info = Udt.find_by(type_hash: type_hash)
73+
CkbUtils.hash_value_to_s(
74+
symbol: udt_info.symbol,
75+
amount: amount,
76+
decimal: udt_info.decimal,
77+
type_hash: type_hash,
78+
published: !!udt_info.published,
79+
)
80+
else
81+
CkbUtils.hash_value_to_s(symbol: "CKB", amount: amount)
82+
end
83+
end
84+
end
85+
86+
def as_json(_options = {})
87+
CkbUtils.hash_value_to_s(
88+
total_nodes:,
89+
total_channels:,
90+
total_capacity:,
91+
mean_value_locked:,
92+
mean_fee_rate:,
93+
medium_value_locked:,
94+
medium_fee_rate:,
95+
created_at_unixtimestamp:,
96+
).merge(total_liquidity: parsed_total_liquidity)
97+
end
998
end
1099

11100
# == Schema Information
@@ -15,14 +104,15 @@ class FiberStatistic < ApplicationRecord
15104
# id :bigint not null, primary key
16105
# total_nodes :integer
17106
# total_channels :integer
18-
# total_liquidity :bigint
107+
# total_capacity :bigint
19108
# mean_value_locked :bigint
20109
# mean_fee_rate :integer
21110
# medium_value_locked :bigint
22111
# medium_fee_rate :integer
23112
# created_at_unixtimestamp :integer
24113
# created_at :datetime not null
25114
# updated_at :datetime not null
115+
# total_liquidity :jsonb
26116
#
27117
# Indexes
28118
#

app/workers/fiber_graph_detect_worker.rb

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -122,41 +122,9 @@ def extract_peer_id(addresses)
122122
end
123123

124124
def compute_statistic
125-
total_nodes = FiberGraphNode.count
126-
total_channels = FiberGraphChannel.count
127-
# 资金总量
128-
total_liquidity = FiberGraphChannel.sum(:capacity)
129-
# 资金均值
130-
mean_value_locked = total_channels.zero? ? 0.0 : total_liquidity.to_f / total_channels
131-
# fee 均值
132-
mean_fee_rate = FiberGraphChannel.average("fee_rate_of_node1 + fee_rate_of_node2") || 0.0
133-
# 获取 capacity 的数据
134-
capacities = FiberGraphChannel.pluck(:capacity).compact
135-
# 获取 fee_rate_of_node1 和 fee_rate_of_node2 的数据并合并
136-
fee_rate_of_node1 = FiberGraphChannel.pluck(:fee_rate_of_node1).compact
137-
fee_rate_of_node2 = FiberGraphChannel.pluck(:fee_rate_of_node2).compact
138-
combined_fee_rates = fee_rate_of_node1 + fee_rate_of_node2
139-
# 计算中位数
140-
medium_value_locked = calculate_median(capacities)
141-
medium_fee_rate = calculate_median(combined_fee_rates)
142125
created_at_unixtimestamp = Time.now.beginning_of_day.to_i
143-
FiberStatistic.upsert(
144-
{ total_nodes:, total_channels:, total_liquidity:,
145-
mean_value_locked:, mean_fee_rate:, medium_value_locked:,
146-
medium_fee_rate:, created_at_unixtimestamp: }, unique_by: %i[created_at_unixtimestamp]
147-
)
148-
end
149-
150-
def calculate_median(array)
151-
sorted = array.sort
152-
count = sorted.size
153-
return nil if count.zero?
154-
155-
if count.odd?
156-
sorted[count / 2] # 奇数个,取中间值
157-
else
158-
(sorted[(count / 2) - 1] + sorted[count / 2]).to_f / 2 # 偶数个,取中间两个的平均值
159-
end
126+
statistic = FiberStatistic.find_or_create_by!(created_at_unixtimestamp:)
127+
statistic.reset_all!
160128
end
161129

162130
def rpc
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class AddTotalLiquidityToFiberStatistics < ActiveRecord::Migration[7.0]
2+
def change
3+
rename_column :fiber_statistics, :total_liquidity, :total_capacity
4+
add_column :fiber_statistics, :total_liquidity, :jsonb
5+
end
6+
end

db/structure.sql

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,7 +1770,9 @@ CREATE TABLE public.fiber_graph_channels (
17701770
last_updated_timestamp_of_node2 bigint,
17711771
fee_rate_of_node1 numeric(30,0) DEFAULT 0.0,
17721772
fee_rate_of_node2 numeric(30,0) DEFAULT 0.0,
1773-
deleted_at timestamp(6) without time zone
1773+
deleted_at timestamp(6) without time zone,
1774+
cell_output_id bigint,
1775+
address_id bigint
17741776
);
17751777

17761778

@@ -1876,14 +1878,15 @@ CREATE TABLE public.fiber_statistics (
18761878
id bigint NOT NULL,
18771879
total_nodes integer,
18781880
total_channels integer,
1879-
total_liquidity bigint,
1881+
total_capacity bigint,
18801882
mean_value_locked bigint,
18811883
mean_fee_rate integer,
18821884
medium_value_locked bigint,
18831885
medium_fee_rate integer,
18841886
created_at_unixtimestamp integer,
18851887
created_at timestamp(6) without time zone NOT NULL,
1886-
updated_at timestamp(6) without time zone NOT NULL
1888+
updated_at timestamp(6) without time zone NOT NULL,
1889+
total_liquidity jsonb
18871890
);
18881891

18891892

@@ -5114,6 +5117,13 @@ CREATE INDEX index_fiber_channels_on_fiber_peer_id ON public.fiber_channels USIN
51145117
CREATE UNIQUE INDEX index_fiber_channels_on_peer_id_and_channel_id ON public.fiber_channels USING btree (peer_id, channel_id);
51155118

51165119

5120+
--
5121+
-- Name: index_fiber_graph_channels_on_address_id; Type: INDEX; Schema: public; Owner: -
5122+
--
5123+
5124+
CREATE INDEX index_fiber_graph_channels_on_address_id ON public.fiber_graph_channels USING btree (address_id);
5125+
5126+
51175127
--
51185128
-- Name: index_fiber_graph_channels_on_channel_outpoint; Type: INDEX; Schema: public; Owner: -
51195129
--
@@ -6401,6 +6411,8 @@ INSERT INTO "schema_migrations" (version) VALUES
64016411
('20250218062041'),
64026412
('20250311084903'),
64036413
('20250318021630'),
6404-
('20250403090946');
6414+
('20250402032340'),
6415+
('20250403090946'),
6416+
('20250408020030');
64056417

64066418

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
namespace :migration do
2+
desc "Usage: RAILS_ENV=production bundle exec rake migration:fix_account_book_income[0,1000000]"
3+
task :fix_account_book_income, %i[start_block end_block] => :environment do |_, args|
4+
(args[:start_block].to_i..args[:end_block].to_i).to_a.each_slice(1000).each do |range|
5+
block_numbers = AccountBook.where("block_number >= ? and block_number <= ?", range[0], range[-1]).
6+
select(:block_number, :address_id).
7+
group(:block_number, :address_id).
8+
having("COUNT(*) > 1").
9+
distinct.
10+
pluck(:block_number)
11+
attrs = Set.new
12+
CkbTransaction.joins(:block).includes(:inputs, :outputs).where(block: { number: block_numbers }).each do |tx|
13+
outputs = tx.outputs.pluck(:address_id, :capacity).group_by { |item| item[0] }.
14+
transform_values { |values| values.sum { |v| v[1] } }
15+
inputs = tx.inputs.pluck(:address_id, :capacity).group_by { |item| item[0] }.
16+
transform_values { |values| values.sum { |v| v[1] } }
17+
address_ids = (outputs.keys + inputs.keys).uniq
18+
address_ids.each do |address_id|
19+
income = (outputs[address_id] || 0) - (inputs[address_id] || 0)
20+
attrs << { address_id:, ckb_transaction_id: tx.id, income: }
21+
end
22+
end
23+
AccountBook.upsert_all(attrs.to_a, unique_by: %i[address_id ckb_transaction_id]) if attrs.present?
24+
end
25+
26+
puts "done"
27+
end
28+
end

0 commit comments

Comments
 (0)