diff --git a/app/models/cell_output.rb b/app/models/cell_output.rb index 05758bc04..d52fa062a 100644 --- a/app/models/cell_output.rb +++ b/app/models/cell_output.rb @@ -27,7 +27,7 @@ class CellOutput < ApplicationRecord # the cell_inputs won't always be the same as `consumed_by`.`cell_inputs` has_many :cell_inputs, foreign_key: :previous_cell_output_id belongs_to :deployed_cell, optional: true - has_one :referring_cell + has_many :referring_cells # the block_id is actually the same as ckb_transaction.block_id, must be on chain # but one cell may be included by pending transactions, so block_id may be null belongs_to :block, optional: true diff --git a/app/models/ckb_transaction.rb b/app/models/ckb_transaction.rb index df38016b3..376fad136 100644 --- a/app/models/ckb_transaction.rb +++ b/app/models/ckb_transaction.rb @@ -272,6 +272,7 @@ def normal_tx_display_outputs(previews) display_output = { id: output.id, capacity: output.capacity, + occupied_capacity: output.occupied_capacity, address_hash: output.address_hash, status: output.status, consumed_tx_hash: consumed_tx_hash, @@ -299,7 +300,7 @@ def cellbase_display_outputs cellbase = Cellbase.new(block) cell_outputs_for_display.map do |output| consumed_tx_hash = output.live? ? nil : output.consumed_by.tx_hash - CkbUtils.hash_value_to_s(id: output.id, capacity: output.capacity, address_hash: output.address_hash, + CkbUtils.hash_value_to_s(id: output.id, capacity: output.capacity, occupied_capacity: output.occupied_capacity, address_hash: output.address_hash, target_block_number: cellbase.target_block_number, base_reward: cellbase.base_reward, commit_reward: cellbase.commit_reward, proposal_reward: cellbase.proposal_reward, secondary_reward: cellbase.secondary_reward, status: output.status, consumed_tx_hash: consumed_tx_hash) end end @@ -315,6 +316,7 @@ def normal_tx_display_inputs(previews) next({ from_cellbase: false, capacity: "", + occupied_capacity: "", address_hash: "", generated_tx_hash: cell_input.previous_tx_hash, cell_index: cell_input.previous_index, @@ -329,6 +331,7 @@ def normal_tx_display_inputs(previews) id: previous_cell_output.id, from_cellbase: false, capacity: previous_cell_output.capacity, + occupied_capacity: previous_cell_output.occupied_capacity, address_hash: previous_cell_output.address_hash, generated_tx_hash: previous_cell_output.ckb_transaction.tx_hash, cell_index: previous_cell_output.cell_index, @@ -420,6 +423,7 @@ def cellbase_display_inputs id: nil, from_cellbase: true, capacity: nil, + occupied_capacity: nil, address_hash: nil, target_block_number: cellbase.target_block_number, generated_tx_hash: tx_hash diff --git a/app/models/referring_cell.rb b/app/models/referring_cell.rb index 49f8cf65d..9ae25ebf2 100644 --- a/app/models/referring_cell.rb +++ b/app/models/referring_cell.rb @@ -18,25 +18,26 @@ def self.create_initial_data_for_ckb_transaction(ckb_transaction) outputs = ckb_transaction.outputs (inputs + outputs).each do |cell| - contract = cell.lock_script.contract - contract ||= cell.type_script&.contract + contracts = [cell.lock_script.contract, cell.type_script&.contract].compact - next unless contract + next if contracts.empty? - if cell.live? - ReferringCell.create_or_find_by( - cell_output_id: cell.id, - ckb_transaction_id: ckb_transaction.id, - contract_id: contract.id - ) - elsif cell.dead? - referring_cell = ReferringCell.find_by( - cell_output_id: cell.id, - ckb_transaction_id: ckb_transaction.id, - contract_id: contract.id - ) + contracts.each do |contract| + if cell.live? + ReferringCell.create_or_find_by( + cell_output_id: cell.id, + ckb_transaction_id: ckb_transaction.id, + contract_id: contract.id + ) + elsif cell.dead? + referring_cell = ReferringCell.find_by( + cell_output_id: cell.id, + ckb_transaction_id: ckb_transaction.id, + contract_id: contract.id + ) - referring_cell.destroy if referring_cell + referring_cell.destroy if referring_cell + end end end end @@ -55,6 +56,5 @@ def self.create_initial_data_for_ckb_transaction(ckb_transaction) # # Indexes # -# index_referring_cells_on_cell_output_id (cell_output_id) UNIQUE # index_referring_cells_on_contract_id_and_cell_output_id (contract_id,cell_output_id) UNIQUE # diff --git a/db/migrate/20231017074221_remove_referring_cell_cell_output_id_index.rb b/db/migrate/20231017074221_remove_referring_cell_cell_output_id_index.rb new file mode 100644 index 000000000..84745cc36 --- /dev/null +++ b/db/migrate/20231017074221_remove_referring_cell_cell_output_id_index.rb @@ -0,0 +1,5 @@ +class RemoveReferringCellCellOutputIdIndex < ActiveRecord::Migration[7.0] + def change + remove_index :referring_cells, name: :index_referring_cells_on_cell_output_id, column: :cell_output_id + end +end diff --git a/db/structure.sql b/db/structure.sql index 3d2eae987..dcfe4f495 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -3965,13 +3965,6 @@ CREATE INDEX index_pool_transaction_entries_on_tx_hash ON public.pool_transactio CREATE INDEX index_pool_transaction_entries_on_tx_status ON public.pool_transaction_entries USING btree (tx_status); --- --- Name: index_referring_cells_on_cell_output_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX index_referring_cells_on_cell_output_id ON public.referring_cells USING btree (cell_output_id); - - -- -- Name: index_referring_cells_on_contract_id_and_cell_output_id; Type: INDEX; Schema: public; Owner: - -- @@ -4756,6 +4749,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20230829061910'), ('20230913091025'), ('20230914120928'), -('20230918033957'); +('20230918033957'), +('20231017074221'); diff --git a/lib/tasks/migration/generate_referring_cells.rake b/lib/tasks/migration/generate_referring_cells.rake index db1a5f4c5..d05877024 100644 --- a/lib/tasks/migration/generate_referring_cells.rake +++ b/lib/tasks/migration/generate_referring_cells.rake @@ -8,16 +8,42 @@ namespace :migration do outputs.each do |output| progress_bar.increment - contract = output.lock_script&.contract - contract ||= output.type_script&.contract + contracts = [output.lock_script.contract, output.type_script&.contract].compact - next unless contract + next if contracts.empty? - ReferringCell.create_or_find_by( - cell_output_id: output.id, - ckb_transaction_id: output.ckb_transaction_id, - contract_id: contract.id - ) + contracts.each do |contract| + ReferringCell.create_or_find_by( + cell_output_id: output.id, + ckb_transaction_id: output.ckb_transaction_id, + contract_id: contract.id + ) + end + end + end + + puts "done" + end + + desc "Usage: RAILS_ENV=production bundle exec rake migration:generate_missed_type_script_contract_referring_cells" + task generate_missed_type_script_contract_referring_cells: :environment do + contract_hashes = Contract.where(role: "type_script").pluck(:code_hash) + binary_hashes = CkbUtils.hexes_to_bins(contract_hashes) + contract_type_ids = TypeScript.where(code_hash: binary_hashes).pluck(:id) + contract_type_ids.each do |type_id| + puts "============#{type_id}" + live_cells = CellOutput.live.where(type_script_id: type_id) + + live_cells.find_in_batches do |outputs| + outputs.each do |output| + contract = output.type_script&.contract + + ReferringCell.create_or_find_by( + cell_output_id: output.id, + ckb_transaction_id: output.ckb_transaction_id, + contract_id: contract.id + ) + end end end diff --git a/test/models/ckb_sync/node_data_processor_test.rb b/test/models/ckb_sync/node_data_processor_test.rb index ef2d16e5b..ca61d1a42 100644 --- a/test/models/ckb_sync/node_data_processor_test.rb +++ b/test/models/ckb_sync/node_data_processor_test.rb @@ -171,7 +171,6 @@ class NodeDataProcessorTest < ActiveSupport::TestCase assert_no_changes -> { tx.reload.tx_status } do node_data_processor.process_block(node_block) end - end end @@ -1313,7 +1312,7 @@ class NodeDataProcessorTest < ActiveSupport::TestCase block = Block.last cellbase = Cellbase.new(block) expected_cellbase_display_inputs = [ - CkbUtils.hash_value_to_s(id: nil, from_cellbase: true, capacity: nil, + CkbUtils.hash_value_to_s(id: nil, from_cellbase: true, capacity: nil, occupied_capacity: nil, address_hash: nil, target_block_number: cellbase.target_block_number, generated_tx_hash: block.cellbase.tx_hash) ] @@ -1351,7 +1350,7 @@ class NodeDataProcessorTest < ActiveSupport::TestCase output = local_ckb_transactions.first.outputs.order(:id).first cellbase = Cellbase.new(local_block) expected_display_outputs = [ - CkbUtils.hash_value_to_s(id: output.id, capacity: output.capacity, + CkbUtils.hash_value_to_s(id: output.id, capacity: output.capacity, occupied_capacity: output.occupied_capacity, address_hash: output.address_hash, target_block_number: cellbase.target_block_number, base_reward: cellbase.base_reward, commit_reward: cellbase.commit_reward, proposal_reward: cellbase.proposal_reward, secondary_reward: cellbase.secondary_reward, status: "live", consumed_tx_hash: nil) ] @@ -1394,7 +1393,7 @@ class NodeDataProcessorTest < ActiveSupport::TestCase expected_cellbase_display_outputs = block.cellbase.cell_outputs.order(:id).map do |cell_output| consumed_tx_hash = cell_output.live? ? nil : cell_output.consumed_by.tx_hash - CkbUtils.hash_value_to_s(id: cell_output.id, capacity: cell_output.capacity, + CkbUtils.hash_value_to_s(id: cell_output.id, capacity: cell_output.capacity, occupied_capacity: cell_output.occupied_capacity, address_hash: cell_output.address_hash, target_block_number: cellbase.target_block_number, base_reward: cellbase.base_reward, commit_reward: cellbase.commit_reward, proposal_reward: cellbase.proposal_reward, secondary_reward: cellbase.secondary_reward, status: cell_output.status, consumed_tx_hash: consumed_tx_hash) end assert_equal expected_cellbase_display_outputs, block.cellbase.display_outputs @@ -1438,7 +1437,7 @@ class NodeDataProcessorTest < ActiveSupport::TestCase cell_output = block.cellbase.cell_outputs.first expected_cellbase_display_outputs = [ CkbUtils.hash_value_to_s(id: cell_output.id, - capacity: cell_output.capacity, address_hash: cell_output.address_hash, target_block_number: cellbase.target_block_number, base_reward: cellbase.base_reward, commit_reward: cellbase.commit_reward, proposal_reward: cellbase.proposal_reward, secondary_reward: cellbase.secondary_reward, status: "live", consumed_tx_hash: nil) + capacity: cell_output.capacity, occupied_capacity: cell_output.occupied_capacity, address_hash: cell_output.address_hash, target_block_number: cellbase.target_block_number, base_reward: cellbase.base_reward, commit_reward: cellbase.commit_reward, proposal_reward: cellbase.proposal_reward, secondary_reward: cellbase.secondary_reward, status: "live", consumed_tx_hash: nil) ] assert_equal expected_cellbase_display_outputs, block.cellbase.display_outputs diff --git a/test/models/ckb_transaction_test.rb b/test/models/ckb_transaction_test.rb index 926c47a1d..85f51f714 100644 --- a/test/models/ckb_transaction_test.rb +++ b/test/models/ckb_transaction_test.rb @@ -79,7 +79,7 @@ class CkbTransactionTest < ActiveSupport::TestCase ckb_transaction = create(:ckb_transaction, :with_multiple_inputs_and_outputs) expected_attributes = %i( - id from_cellbase capacity address_hash + id from_cellbase capacity occupied_capacity address_hash generated_tx_hash cell_type cell_index since ).sort @@ -91,7 +91,7 @@ class CkbTransactionTest < ActiveSupport::TestCase ckb_transaction = create(:ckb_transaction, :with_single_output, is_cellbase: true) expected_attributes = %i( - id from_cellbase capacity address_hash + id from_cellbase capacity occupied_capacity address_hash target_block_number generated_tx_hash ) @@ -103,7 +103,7 @@ class CkbTransactionTest < ActiveSupport::TestCase ckb_transaction = create(:ckb_transaction, :with_multiple_inputs_and_outputs) expected_attributes = %i( - id capacity address_hash status consumed_tx_hash + id capacity occupied_capacity address_hash status consumed_tx_hash cell_type ).sort @@ -117,7 +117,7 @@ class CkbTransactionTest < ActiveSupport::TestCase ckb_transaction = create(:ckb_transaction, :with_single_output, is_cellbase: true, block: block) expected_attributes = %i( - id capacity address_hash target_block_number + id capacity occupied_capacity address_hash target_block_number base_reward commit_reward proposal_reward secondary_reward status consumed_tx_hash ) @@ -201,6 +201,7 @@ class CkbTransactionTest < ActiveSupport::TestCase id: nervos_dao_withdrawing_cell.id, from_cellbase: false, capacity: nervos_dao_withdrawing_cell.capacity, + occupied_capacity: nervos_dao_withdrawing_cell.occupied_capacity, address_hash: nervos_dao_withdrawing_cell.address_hash, generated_tx_hash: nervos_dao_withdrawing_cell.ckb_transaction.tx_hash, compensation_started_block_number: started_block.number, @@ -218,7 +219,7 @@ class CkbTransactionTest < ActiveSupport::TestCase } ).sort expected_attributes = %i( - id from_cellbase capacity address_hash generated_tx_hash compensation_started_block_number + id from_cellbase capacity occupied_capacity address_hash generated_tx_hash compensation_started_block_number compensation_ended_block_number compensation_started_timestamp compensation_ended_timestamp interest cell_type cell_index since locked_until_block_number locked_until_block_timestamp ).sort @@ -269,6 +270,7 @@ class CkbTransactionTest < ActiveSupport::TestCase id: deposit_output_cell.id, from_cellbase: false, capacity: deposit_output_cell.capacity, + occupied_capacity: deposit_output_cell.occupied_capacity, address_hash: deposit_output_cell.address_hash, generated_tx_hash: deposit_output_cell.ckb_transaction.tx_hash, compensation_started_block_number: started_block.number, @@ -284,7 +286,7 @@ class CkbTransactionTest < ActiveSupport::TestCase } ).sort expected_attributes = %i( - id from_cellbase capacity address_hash generated_tx_hash interest cell_type + id from_cellbase capacity occupied_capacity address_hash generated_tx_hash interest cell_type compensation_ended_block_number compensation_ended_timestamp compensation_started_block_number compensation_started_timestamp cell_index since ).sort @@ -301,12 +303,12 @@ class CkbTransactionTest < ActiveSupport::TestCase dao_output = ckb_transaction.outputs.first dao_output.update(cell_type: "nervos_dao_withdrawing") expected_attributes = %i( - id capacity address_hash status consumed_tx_hash + id capacity occupied_capacity address_hash status consumed_tx_hash cell_type ).sort consumed_tx_hash = dao_output.live? ? nil : dao_output.consumed_by.tx_hash expected_display_output = CkbUtils.hash_value_to_s(id: dao_output.id, - capacity: dao_output.capacity, address_hash: dao_output.address_hash, status: dao_output.status, consumed_tx_hash: consumed_tx_hash, cell_type: dao_output.cell_type).sort + capacity: dao_output.capacity, occupied_capacity: dao_output.occupied_capacity, address_hash: dao_output.address_hash, status: dao_output.status, consumed_tx_hash: consumed_tx_hash, cell_type: dao_output.cell_type).sort display_outputs = ckb_transaction.display_outputs assert_equal expected_attributes - display_outputs.first.keys, [] assert_equal expected_display_output, display_outputs.first.sort @@ -343,6 +345,7 @@ class CkbTransactionTest < ActiveSupport::TestCase id: udt_cell_output.id, from_cellbase: false, capacity: udt_cell_output.capacity, + occupied_capacity: udt_cell_output.occupied_capacity, address_hash: udt_cell_output.address_hash, generated_tx_hash: udt_cell_output.ckb_transaction.tx_hash, cell_index: udt_cell_output.cell_index, @@ -383,6 +386,7 @@ class CkbTransactionTest < ActiveSupport::TestCase expected_display_input = CkbUtils.hash_value_to_s( id: udt_cell_output.id, capacity: udt_cell_output.capacity, + occupied_capacity: udt_cell_output.occupied_capacity, address_hash: udt_cell_output.address_hash, status: udt_cell_output.status, consumed_tx_hash: nil, @@ -423,6 +427,7 @@ class CkbTransactionTest < ActiveSupport::TestCase id: m_nft_cell_output.id, from_cellbase: false, capacity: m_nft_cell_output.capacity, + occupied_capacity: m_nft_cell_output.occupied_capacity, address_hash: m_nft_cell_output.address_hash, generated_tx_hash: m_nft_cell_output.ckb_transaction.tx_hash, cell_index: m_nft_cell_output.cell_index, @@ -465,6 +470,7 @@ class CkbTransactionTest < ActiveSupport::TestCase id: m_nft_cell_output.id, from_cellbase: false, capacity: m_nft_cell_output.capacity, + occupied_capacity: m_nft_cell_output.occupied_capacity, address_hash: m_nft_cell_output.address_hash, generated_tx_hash: m_nft_cell_output.ckb_transaction.tx_hash, cell_index: m_nft_cell_output.cell_index, @@ -525,6 +531,7 @@ class CkbTransactionTest < ActiveSupport::TestCase id: m_nft_cell_output.id, from_cellbase: false, capacity: m_nft_cell_output.capacity, + occupied_capacity: m_nft_cell_output.occupied_capacity, address_hash: m_nft_cell_output.address_hash, generated_tx_hash: m_nft_cell_output.ckb_transaction.tx_hash, cell_index: m_nft_cell_output.cell_index, @@ -558,6 +565,7 @@ class CkbTransactionTest < ActiveSupport::TestCase expected_display_output = CkbUtils.hash_value_to_s( id: m_nft_cell_output.id, capacity: m_nft_cell_output.capacity, + occupied_capacity: m_nft_cell_output.occupied_capacity, address_hash: m_nft_cell_output.address_hash, status: m_nft_cell_output.status, consumed_tx_hash: nil, @@ -586,6 +594,7 @@ class CkbTransactionTest < ActiveSupport::TestCase expected_display_output = CkbUtils.hash_value_to_s( id: m_nft_cell_output.id, capacity: m_nft_cell_output.capacity, + occupied_capacity: m_nft_cell_output.occupied_capacity, address_hash: m_nft_cell_output.address_hash, status: m_nft_cell_output.status, consumed_tx_hash: nil, @@ -639,6 +648,7 @@ class CkbTransactionTest < ActiveSupport::TestCase expected_display_output = CkbUtils.hash_value_to_s( id: m_nft_cell_output.id, capacity: m_nft_cell_output.capacity, + occupied_capacity: m_nft_cell_output.occupied_capacity, address_hash: m_nft_cell_output.address_hash, status: m_nft_cell_output.status, consumed_tx_hash: nil,