Skip to content

Commit

Permalink
Merge branch 'issue-297-2' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
zmcNotafraid committed Jan 1, 2025
2 parents d16e366 + 4b15d32 commit 6200717
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 64 deletions.
106 changes: 71 additions & 35 deletions app/jobs/revert_block_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ def perform(local_tip_block = nil)
uniq.concat(local_tip_block.cell_outputs.m_nft_token.pluck(:type_hash).uniq)
end
benchmark :recalculate_udt_transactions_count, local_tip_block
benchmark :recalculate_dao_contract_transactions_count, local_tip_block
benchmark :decrease_records_count, local_tip_block

ApplicationRecord.benchmark "invalid! block" do
Expand Down Expand Up @@ -60,14 +59,6 @@ def update_address_balance_and_ckb_transactions_count(local_tip_block)
AddressBlockSnapshot.where(block_id: local_tip_block.id).delete_all
end

def recalculate_dao_contract_transactions_count(local_tip_block)
dao_transactions_count = local_tip_block.ckb_transactions.where("tags @> array[?]::varchar[]", ["dao"]).count
if dao_transactions_count > 0
DaoContract.default_contract.decrement!(:ckb_transactions_count,
dao_transactions_count)
end
end

def recalculate_udt_transactions_count(local_tip_block)
udt_ids = local_tip_block.ckb_transactions.map(&:contained_udt_ids).flatten
udt_counts = udt_ids.each_with_object(Hash.new(0)) { |udt_id, counts| counts[udt_id] += 1 }
Expand All @@ -85,15 +76,6 @@ def recalculate_udt_transactions_count(local_tip_block)
Udt.upsert_all(udt_counts_value) if udt_counts_value.present?
end

def revert_dao_contract_related_operations(local_tip_block)
dao_events = DaoEvent.where(block: local_tip_block).processed
dao_contract = DaoContract.default_contract
revert_withdraw_from_dao(dao_contract, dao_events)
revert_issue_interest(dao_contract, dao_events)
revert_deposit_to_dao(dao_contract, dao_events)
dao_contract.update(depositors_count: DaoEvent.depositor.count)
end

def recalculate_udt_accounts(udt_type_hashes, local_tip_block)
return if udt_type_hashes.blank?

Expand Down Expand Up @@ -122,38 +104,92 @@ def revert_mining_info(local_tip_block)
miner_address.decrement!(:mined_blocks_count)
end

def revert_issue_interest(dao_contract, dao_events)
issue_interest_dao_events = dao_events.where(event_type: "issue_interest")
def revert_dao_contract_related_operations(local_tip_block)
dao_events = DaoEvent.where(block: local_tip_block).processed
dao_transactions_count = local_tip_block.ckb_transactions.where("tags @> array[?]::varchar[]", ["dao"]).count
dao_contract = DaoContract.default_contract

withdraw_transactions_count, withdraw_total_deposit = revert_withdraw_from_dao(dao_events)
claimed_compensation = revert_issue_interest(dao_events)
deposit_transactions_count, deposit_total_deposit = revert_deposit_to_dao(dao_events)

dao_events.update_all(status: "reverted")
dao_contract.update!(deposit_transactions_count: dao_contract.deposit_transactions_count - deposit_transactions_count,
withdraw_transactions_count: dao_contract.withdraw_transactions_count - withdraw_transactions_count,
total_deposit: dao_contract.total_deposit + withdraw_total_deposit - deposit_total_deposit,
claimed_compensation: dao_contract.claimed_compensation - claimed_compensation,
ckb_transactions_count: dao_contract.ckb_transactions_count - dao_transactions_count,
depositors_count: DaoEvent.depositor.count)
end

def revert_issue_interest(dao_events)
issue_interest_dao_events = dao_events.issue_interest
claimed_compensation = 0
address_attrs = {}
issue_interest_dao_events.each do |event|
dao_contract.decrement!(:claimed_compensation, event.value)
claimed_compensation += event.value

address = event.address
address.decrement!(:interest, event.value)
event.reverted!
address_attrs[address.id] ||= {
id: address.id,
interest: address.interest,
}
address_attrs[address.id][:interest] -= event.value
end
upsert_data = address_attrs.values
Address.upsert_all(upsert_data, unique_by: :id) if upsert_data.present?
claimed_compensation
end

def revert_withdraw_from_dao(dao_contract, dao_events)
withdraw_from_dao_events = dao_events.where(event_type: "withdraw_from_dao")
def revert_withdraw_from_dao(dao_events)
withdraw_from_dao_events = dao_events.includes(:address).withdraw_from_dao

ids = withdraw_from_dao_events.pluck(:ckb_transaction_id)
DaoEvent.processed.where(withdrawn_transaction_id: ids).update_all(withdrawn_transaction_id: nil)

redundant_total_deposit = 0
address_attrs = {}
withdraw_from_dao_events.each do |event|
dao_contract.decrement!(:withdraw_transactions_count)
dao_contract.increment!(:total_deposit, event.value)
redundant_total_deposit += event.value

address = event.address
address.increment!(:dao_deposit, event.value)
event.reverted!
address_attrs[address.id] ||= {
id: address.id,
dao_deposit: address.dao_deposit,
is_depositor: address.is_depositor,
}
address_attrs[address.id][:dao_deposit] += event.value
address_attrs[address.id][:is_depositor] = true
end

upsert_data = address_attrs.values
Address.upsert_all(upsert_data, unique_by: :id) if upsert_data.present?

[withdraw_from_dao_events.size, redundant_total_deposit]
end

def revert_deposit_to_dao(dao_contract, dao_events)
deposit_to_dao_events = dao_events.where(event_type: "deposit_to_dao")
def revert_deposit_to_dao(dao_events)
deposit_to_dao_events = dao_events.deposit_to_dao
redundant_total_deposit = 0
address_attrs = {}

deposit_to_dao_events.each do |event|
redundant_total_deposit += event.value

address = event.address
address.decrement!(:dao_deposit, event.value)
dao_contract.decrement!(:total_deposit, event.value)
dao_contract.decrement!(:deposit_transactions_count)
event.reverted!
address_attrs[address.id] ||= {
id: address.id,
dao_deposit: address.dao_deposit,
}
address_attrs[address.id][:dao_deposit] -= event.value
end

upsert_data = address_attrs.values
address_ids = address_attrs.values.map { |hash| hash[:id] }
Address.upsert_all(upsert_data, unique_by: :id) if upsert_data.present?
Address.where(id: address_ids, dao_deposit: 0).update_all(is_depositor: false)

[deposit_to_dao_events.size, redundant_total_deposit]
end

def revert_block_rewards(local_tip_block)
Expand Down
4 changes: 3 additions & 1 deletion app/models/ckb_sync/new_node_data_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,10 @@ def process_deposit_dao_events!(local_block, dao_contract)
addresses_deposit_info[address.id] =
{
dao_deposit: address.dao_deposit.to_i + dao_output.capacity,
is_depositor: true,

}
end
addresses_deposit_info[address.id][:is_depositor] = true
deposit_amount += dao_output.capacity
deposit_transaction_ids << dao_output.ckb_transaction_id
dao_events_attributes << {
Expand Down Expand Up @@ -351,6 +352,7 @@ def update_addresses_dao_info(addrs_deposit_info)
id: address_id,
dao_deposit: address_info[:dao_deposit],
interest: address_info[:interest],
is_depositor: address_info[:is_depositor],
}
end
Address.upsert_all(addresses_deposit_attributes, record_timestamps: true) if addresses_deposit_attributes.present?
Expand Down
23 changes: 0 additions & 23 deletions test/controllers/api/v1/daily_statistics_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,29 +94,6 @@ class DailyStatisticsControllerTest < ActionDispatch::IntegrationTest
assert_equal response_json, response.body
end

test "should return recent year transactions count and timestamp" do
target_date = Time.current.beginning_of_year

i = 1
o_date = i.days.ago
while o_date > target_date
newly_created_object = create(:daily_statistic, created_at_unixtimestamp: o_date)
i += 1
o_date = i.days.ago
end
daily_statistic_data = DailyStatistic.order(:created_at_unixtimestamp).
where("created_at_unixtimestamp > ?", target_date.to_i).
valid_indicators
valid_get api_v1_daily_statistic_url("transactions_count")

assert_equal [%w(transactions_count created_at_unixtimestamp).sort], json.dig("data").map { |item|
item.dig("attributes").keys.sort
}.uniq
assert_equal DailyStatisticSerializer.new(daily_statistic_data, params: { indicator: "transactions_count" }).serialized_json,
response.body
assert_equal ((Time.current - target_date) / (24 * 60 * 60)).to_i, json.dig("data").size
end

test "should return recent all days average hash rate" do
100.times do |i|
create(:daily_statistic, created_at_unixtimestamp: (360 - i).days.ago.to_i)
Expand Down
12 changes: 8 additions & 4 deletions test/models/ckb_sync/dao_events_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ class DaoEventsTest < ActiveSupport::TestCase
node_data_processor.call
end

deposit_to_dao_events = local_block.dao_events.where(event_type: "withdraw_from_dao")
assert_equal ["reverted"], deposit_to_dao_events.pluck(:status).uniq
dao_events = local_block.dao_events.where(event_type: "withdraw_from_dao")
assert_equal ["reverted"], dao_events.pluck(:status).uniq
end
end

Expand Down Expand Up @@ -366,13 +366,15 @@ class DaoEventsTest < ActiveSupport::TestCase
node_block = fake_node_block("0x3307186493c5da8b91917924253a5ffd35231151649d0c7e2941aa8801815063")
create(:block, :with_block_hash, number: node_block.header.number - 1)
VCR.use_cassette("blocks/#{DEFAULT_NODE_BLOCK_NUMBER}") do
fake_dao_withdraw_transaction(node_block)
tx = fake_dao_withdraw_transaction(node_block)
assert_equal true, tx.cell_outputs.first.address.is_depositor
DaoContract.default_contract.update(total_deposit: 100000000000)
assert_difference -> { DaoEvent.where(event_type: "withdraw_from_dao").count }, 1 do
node_data_processor.process_block(node_block)
end

deposit_to_dao_events = Block.find_by(number: node_block.header.number).dao_events.where(event_type: "withdraw_from_dao")
assert_equal false, tx.cell_outputs.first.address.is_depositor
assert_equal ["processed"], deposit_to_dao_events.pluck(:status).uniq
assert_equal(%w(block_id ckb_transaction_id address_id contract_id event_type value status block_timestamp withdrawn_transaction_id cell_index), deposit_to_dao_events.first.attribute_names.reject do |attribute|
attribute.in?(%w(created_at updated_at id))
Expand Down Expand Up @@ -540,13 +542,15 @@ class DaoEventsTest < ActiveSupport::TestCase
tx = fake_dao_deposit_transaction(node_block)
output = tx.outputs.first
address = Address.find_or_create_address(output.lock, node_block.header.timestamp)
assert_equal false, address.is_depositor

assert_difference -> { address.reload.dao_deposit }, 10**8 * 1000 do
node_data_processor.process_block(node_block)
end

deposit_to_dao_events = Block.find_by(number: node_block.header.number).dao_events.where(event_type: "deposit_to_dao")
assert_equal ["processed"], deposit_to_dao_events.pluck(:status).uniq
assert_equal true, address.reload.is_depositor
end
end

Expand Down Expand Up @@ -820,7 +824,7 @@ def fake_dao_withdraw_transaction(node_block)
tx_hash: "0x598315db9c7ba144cca74d2e9122ac9b3a3da1641b2975ae321d91ec34f1c0e3",
block:, capacity: 10**8 * 1000,
lock_script_id: lock.id)
cell_output1.address.update(balance: 10**8 * 1000, dao_deposit: 10**8 * 1000)
cell_output1.address.update(balance: 10**8 * 1000, dao_deposit: 10**8 * 1000, is_depositor: true)
cell_output2.address.update(balance: 10**8 * 1000)
tx = node_block.transactions.last
output = tx.outputs.first
Expand Down
3 changes: 2 additions & 1 deletion test/models/ckb_sync/node_data_processor_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2624,11 +2624,12 @@ class NodeDataProcessorTest < ActiveSupport::TestCase
transactions:, header:)
block = node_data_processor.process_block(node_block)
CkbSync::Api.any_instance.stubs(:get_tip_block_number).returns(block.number + 1)
DaoContract.default_contract.update(deposit_transactions_count: 4)

VCR.use_cassette("blocks/#{DEFAULT_NODE_BLOCK_NUMBER}",
record: :new_episodes) do
assert_changes -> {
DaoContract.default_contract.ckb_transactions_count
DaoContract.default_contract.reload.ckb_transactions_count
}, from: 2, to: 0 do
node_data_processor.call
end
Expand Down

0 comments on commit 6200717

Please sign in to comment.