From cc07f010a957996fefdfead4d9a541d9741dc562 Mon Sep 17 00:00:00 2001 From: Rabbit Date: Fri, 28 Jun 2024 09:21:18 +0800 Subject: [PATCH] fix: ensure unique transaction attributes before upsert (#2009) --- app/jobs/import_btc_time_cells_job.rb | 10 ++++++---- app/jobs/import_rgbpp_cells_job.rb | 15 +++++++++------ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/app/jobs/import_btc_time_cells_job.rb b/app/jobs/import_btc_time_cells_job.rb index 2b2600704..a32fb437c 100644 --- a/app/jobs/import_btc_time_cells_job.rb +++ b/app/jobs/import_btc_time_cells_job.rb @@ -33,6 +33,7 @@ def perform(cell_ids) end rescue StandardError => e Rails.logger.error("ImportBtcTimeCells failed: #{e.message}") + Rails.logger.error("Backtrace:\n#{e.backtrace.join("\n")}") end def build_utxo_map(cell_outputs) @@ -61,7 +62,7 @@ def fetch_raw_transactions!(utxo_map) end def build_transactions!(cell_outputs, raw_tx_data, utxo_map) - transaction_attributes = [] + transaction_attributes = {} cell_outputs.each do |cell_output| txid = utxo_map[cell_output.id] @@ -70,7 +71,7 @@ def build_transactions!(cell_outputs, raw_tx_data, utxo_map) next unless raw_tx created_at = Time.at((cell_output.block_timestamp / 1000).to_i).in_time_zone - transaction_attributes << { + transaction_attributes[txid] = { txid: raw_tx["txid"], tx_hash: raw_tx["hash"], time: raw_tx["time"], @@ -80,8 +81,9 @@ def build_transactions!(cell_outputs, raw_tx_data, utxo_map) } end - BitcoinTransaction.upsert_all(transaction_attributes, unique_by: :txid) - BitcoinTransaction.where(txid: transaction_attributes.map { _1[:txid] }).index_by(&:txid) + unique_transaction_attributes = transaction_attributes.values + BitcoinTransaction.upsert_all(unique_transaction_attributes, unique_by: :txid) + BitcoinTransaction.where(txid: unique_transaction_attributes.map { |tx| tx[:txid] }).index_by(&:txid) end def rpc diff --git a/app/jobs/import_rgbpp_cells_job.rb b/app/jobs/import_rgbpp_cells_job.rb index b9762dd8b..11ceb5713 100644 --- a/app/jobs/import_rgbpp_cells_job.rb +++ b/app/jobs/import_rgbpp_cells_job.rb @@ -29,7 +29,7 @@ def perform(cell_ids) # build op_returns op_returns = build_op_returns!(raw_tx, tx, cell_output.ckb_transaction) - op_returns_attributes.concat(op_returns) if op_returns.present? + op_returns_attributes.concat(op_returns).uniq! if op_returns.present? # build vouts vout = build_vout!(raw_tx, tx, out_index, cell_output) @@ -73,6 +73,7 @@ def perform(cell_ids) end rescue StandardError => e Rails.logger.error("ImportRgbppCells failed: #{e.message}") + Rails.logger.error("Backtrace:\n#{e.backtrace.join("\n")}") end def build_utxo_map(cell_outputs) @@ -101,16 +102,17 @@ def fetch_raw_transactions!(utxo_map) end def build_transactions!(cell_outputs, raw_tx_data, utxo_map) - transaction_attributes = [] + transaction_attributes = {} cell_outputs.each do |cell_output| - txid = utxo_map[cell_output.id][:txid] + utxo = utxo_map[cell_output.id] + txid = utxo[:txid] raw_tx = raw_tx_data[txid] next unless raw_tx created_at = Time.at((cell_output.block_timestamp / 1000).to_i).in_time_zone - transaction_attributes << { + transaction_attributes[txid] = { txid: raw_tx["txid"], tx_hash: raw_tx["hash"], time: raw_tx["time"], @@ -120,8 +122,9 @@ def build_transactions!(cell_outputs, raw_tx_data, utxo_map) } end - BitcoinTransaction.upsert_all(transaction_attributes, unique_by: :txid) - BitcoinTransaction.where(txid: transaction_attributes.map { _1[:txid] }).index_by(&:txid) + unique_transaction_attributes = transaction_attributes.values + BitcoinTransaction.upsert_all(unique_transaction_attributes, unique_by: :txid) + BitcoinTransaction.where(txid: unique_transaction_attributes.map { |tx| tx[:txid] }).index_by(&:txid) end def build_op_returns!(raw_tx, tx, ckb_tx)