Skip to content

Commit

Permalink
Issue 495 3 (#1543)
Browse files Browse the repository at this point in the history
* fix: hexes_to_bins method in special value has bug

Signed-off-by: Miles Zhang <[email protected]>

* feat: handle unknown status tx

Signed-off-by: Miles Zhang <[email protected]>

---------

Signed-off-by: Miles Zhang <[email protected]>
  • Loading branch information
zmcNotafraid authored Dec 27, 2023
1 parent b615030 commit d7faa64
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 51 deletions.
6 changes: 3 additions & 3 deletions app/models/ckb_sync/new_node_data_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1210,9 +1210,9 @@ def build_ckb_transactions!(node_block, local_block, inputs, outputs, outputs_da
end
# First update status thus we can use upsert later. otherwise, we may not be able to
# locate correct record according to tx_hash
binary_hashes = CkbUtils.hexes_to_bins(hashes)
pending_txs = CkbTransaction.where(tx_hash: binary_hashes, tx_status: :pending).pluck(:tx_hash, :created_at)
CkbTransaction.where(tx_hash: binary_hashes).update_all tx_status: "committed"
binary_hashes = CkbUtils.hexes_to_bins_sql(hashes)
pending_txs = CkbTransaction.where("tx_hash IN (#{binary_hashes})").where(tx_status: :pending).pluck(:tx_hash, :created_at)
CkbTransaction.where("tx_hash IN (#{binary_hashes})").update_all tx_status: "committed"

txs = CkbTransaction.upsert_all(ckb_transactions_attributes, unique_by: [:tx_status, :tx_hash],
returning: %w(id tx_hash block_timestamp created_at))
Expand Down
6 changes: 3 additions & 3 deletions app/utils/ckb_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,9 @@ def self.shannon_to_byte(shannon)
shannon / (10**8)
end

def self.hexes_to_bins(hashes)
if hashes.is_a?(Array) && hashes.length > 0
hashes.map { |h| [h[2..-1]].pack("H*") }
def self.hexes_to_bins_sql(hex_strings)
if hex_strings.is_a?(Array) && hex_strings.length > 0
hex_strings.map { |hex_string| ActiveRecord::Base.sanitize_sql_array(["E'\\\\x%s'::bytea", hex_string.delete_prefix("0x")]) }.join(", ")
else
[]
end
Expand Down
7 changes: 7 additions & 0 deletions app/workers/pool_transaction_check_worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ def perform
tx.create_reject_reason!(message: reason["reason"])
end
end

if reason["status"] == "unknown"
ApplicationRecord.transaction do
tx.update! tx_status: "rejected"
tx.create_reject_reason!(message: "unknown")
end
end
end
end
end
22 changes: 12 additions & 10 deletions lib/tasks/migration/generate_referring_cells.rake
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ namespace :migration do
desc "Usage: RAILS_ENV=production bundle exec rake migration:generate_referring_cells"
task generate_referring_cells: :environment do
live_cells = CellOutput.live.left_joins(:referring_cell).where(referring_cells: { id: nil })
progress_bar = ProgressBar.create({ total: live_cells.count, format: "%e %B %p%% %c/%C" })
progress_bar = ProgressBar.create({ total: live_cells.count,
format: "%e %B %p%% %c/%C" })

live_cells.find_in_batches do |outputs|
outputs.each do |output|
progress_bar.increment

contracts = [output.lock_script.contract, output.type_script&.contract].compact
contracts = [output.lock_script.contract,
output.type_script&.contract].compact

next if contracts.empty?

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
contract_id: contract.id,
)
end
end
Expand All @@ -28,8 +30,8 @@ namespace :migration do
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)
binary_hashes = CkbUtils.hexes_to_bins_sql(contract_hashes)
contract_type_ids = TypeScript.where("code_hash IN (#{binary_hashes})").pluck(:id)
contract_type_ids.each do |type_id|
puts "============#{type_id}"
live_cells = CellOutput.live.where(type_script_id: type_id)
Expand All @@ -38,11 +40,11 @@ namespace :migration do
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
)
ReferringCell.create_or_find_by(
cell_output_id: output.id,
ckb_transaction_id: output.ckb_transaction_id,
contract_id: contract.id,
)
end
end
end
Expand Down
59 changes: 30 additions & 29 deletions test/utils/ckb_utils_test.rb

Large diffs are not rendered by default.

25 changes: 19 additions & 6 deletions test/workers/pool_transaction_check_worker_test.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
require "test_helper"

class PoolTransactionCheckWorkerTest < ActiveSupport::TestCase
setup do
test "should marked tx to rejected when rpc returns rejected" do
CkbSync::Api.any_instance.stubs(:generate_json_rpc_id).returns(1)
rejected_tx_id = "0xed2049c21ffccfcd26281d60f8f77ff117adb9df9d3f8cbe5fe86e893c66d359"
@pending_tx = create(:pending_transaction,
tx_hash: rejected_tx_id, created_at: 10.minutes.ago)
pending_tx = create(:pending_transaction,
tx_hash: rejected_tx_id, created_at: 10.minutes.ago)

Sidekiq::Testing.inline!
VCR.use_cassette("get_rejected_transaction") do
PoolTransactionCheckWorker.perform_async
assert_equal "rejected", pending_tx.reload.tx_status
assert pending_tx.detailed_message.include?("Resolve failed Dead")
end
end

test "should detect and mark failed tx from pending tx, for inputs" do
test "should marked tx to rejected when rpc returns unknown" do
CkbSync::Api.any_instance.stubs(:generate_json_rpc_id).returns(2)
unknown_tx_id = "0x1cebe4b6ddae45264790835200fe3a4efdc58e3474e552aff2246eb42b79ed2c"
pending_tx = create(:pending_transaction,
tx_hash: unknown_tx_id, created_at: 10.minutes.ago)

Sidekiq::Testing.inline!
VCR.use_cassette("get_rejected_transaction") do
PoolTransactionCheckWorker.perform_async
assert_equal "rejected", @pending_tx.reload.tx_status
assert @pending_tx.detailed_message.include?("Resolve failed Dead")
assert_equal "rejected", pending_tx.reload.tx_status
assert pending_tx.detailed_message.include?("unknown")
end
end
end
33 changes: 33 additions & 0 deletions vcr_fixtures/vcr_cassettes/get_rejected_transaction.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d7faa64

Please sign in to comment.