Skip to content

Commit

Permalink
fix: adjust the count of nft cells change
Browse files Browse the repository at this point in the history
  • Loading branch information
rabbitz committed Feb 19, 2024
1 parent b076be9 commit e8adc3a
Showing 1 changed file with 64 additions and 30 deletions.
94 changes: 64 additions & 30 deletions app/controllers/concerns/cell_data_comparator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ def compare_cells(transaction)
udt_transfers = diff_udt_cells(inputs, outputs)
cota_nft_transfers = diff_cota_nft_cells(transaction, inputs, outputs)
normal_nft_transfers = diff_normal_nft_cells(inputs, outputs)
nft_class_transfers = diff_nft_capacities(inputs, outputs)
dao_transfers = diff_dao_capacities(inputs, outputs)

merged_transfers =
[normal_transfers, udt_transfers, cota_nft_transfers, normal_nft_transfers, nft_class_transfers].reduce do |acc, h|
[normal_transfers, udt_transfers, cota_nft_transfers, normal_nft_transfers, dao_transfers].reduce do |acc, h|
acc.merge(h) { |_, ov, nv| ov + nv }
end

Expand Down Expand Up @@ -73,6 +73,20 @@ def diff_udt_cells(inputs, outputs)
transfers
end

def diff_dao_capacities(inputs, outputs)
transfers = Hash.new { |h, k| h[k] = Array.new }
cell_types = %w(nervos_dao_deposit nervos_dao_withdrawing)
inputs = inputs.where(cell_type: cell_types).group(:address_id, :cell_type).sum(:capacity)
outputs = outputs.where(cell_type: cell_types).group(:address_id, :cell_type).sum(:capacity)

(inputs.keys | outputs.keys).each do |k|
capacity = outputs[k].to_f - inputs[k].to_f
transfers[k[0]] << CkbUtils.hash_value_to_s({ capacity:, cell_type: k[1] })
end

transfers
end

def diff_cota_nft_cells(transaction, inputs, outputs)
transfers = Hash.new { |h, k| h[k] = Array.new }
inputs = inputs.cota_regular.group(:address_id).sum(:capacity)
Expand All @@ -88,58 +102,78 @@ def diff_cota_nft_cells(transaction, inputs, outputs)

def diff_normal_nft_cells(inputs, outputs)
transfers = Hash.new { |h, k| h[k] = Array.new }
cell_types = %w(m_nft_token nrc_721_token spore_cell)
nft_infos = Hash.new { |h, k| h[k] = nil }
cell_types = %w(m_nft_token nrc_721_token spore_cell m_nft_issuer m_nft_class nrc_721_factory cota_registry spore_cluster)

process_nft = ->(c, h) {
process_nft = ->(c, h, o) {
k = [c.address_id, c.cell_type, c.type_hash]
h[k] ||= { capacity: 0.0, count: 0 }
h[k][:capacity] += c.capacity
h[k][:count] -= 1
h[k][:count] += o

unless nft_infos[c.type_hash]
nft_infos[c.type_hash] = nft_info(c)
end
}
inputs = inputs.where(cell_type: cell_types).each_with_object({}) { |c, h| process_nft.call(c, h) }
outputs = outputs.where(cell_type: cell_types).each_with_object({}) { |c, h| process_nft.call(c, h) }
inputs = inputs.where(cell_type: cell_types).each_with_object({}) { |c, h| process_nft.call(c, h, -1) }
outputs = outputs.where(cell_type: cell_types).each_with_object({}) { |c, h| process_nft.call(c, h, 1) }

(inputs.keys | outputs.keys).each do |k|
address_id, cell_type, type_hash = k
token_id, collection_name = token_info(type_hash)
input = inputs[k]
output = outputs[k]
capacity = output&.dig(:capacity).to_f - input&.dig(:capacity).to_f
count = output&.dig(:count).to_i + input&.dig(:count).to_i
transfers[address_id] << CkbUtils.hash_value_to_s({ capacity:, cell_type:, token_id:, collection_name:, count: })
transfer = { capacity:, cell_type:, count: }
transfer.merge!(nft_infos[type_hash]) if nft_infos[type_hash]
transfers[address_id] << CkbUtils.hash_value_to_s(transfer)
end

transfers
end

def diff_nft_capacities(inputs, outputs)
transfers = Hash.new { |h, k| h[k] = Array.new }
cell_types = %w(m_nft_issuer m_nft_class nrc_721_factory cota_registry spore_cluster)
inputs = inputs.where(cell_type: cell_types).group(:address_id, :cell_type).sum(:capacity)
outputs = outputs.where(cell_type: cell_types).group(:address_id, :cell_type).sum(:capacity)

(inputs.keys | outputs.keys).each do |k|
capacity = outputs[k].to_f - inputs[k].to_f
transfers[k[0]] << CkbUtils.hash_value_to_s({ capacity:, cell_type: k[1] })
def nft_info(cell)
case cell.cell_type
when "m_nft_token", "nrc_721_token", "spore_cell"
item = TokenItem.joins(:type_script).where(type_script: { script_hash: cell.type_hash }).take
{ toekn_id: item&.token_id, name: item&.collection&.name }
when "m_nft_issuer"
{ name: CkbUtils.parse_issuer_data(cell.data).info["name"] }
when "m_nft_class"
{ name: CkbUtils.parse_token_class_data(cell.data).name }
when "nrc_721_factory"
type_script = cell.type_script
factory_cell = NrcFactoryCell.find_by(
code_hash: type_script.code_hash,
hash_type: type_script.hash_type,
args: type_script.args,
verified: true,
)
{ name: factory_cell&.name }
when "spore_cluster"
{ name: CkbUtils.parse_spore_cluster_data(cell.data)[:name] }
when "omiga_inscription_info"
type_script = cell.type_script
info = OmigaInscriptionInfo.find_by(
code_hash: type_script.code_hash,
hash_type: type_script.hash_type,
args: type_script.args,
)
{ name: info&.name }
end

transfers
end

def token_info(script_hash)
item = TokenItem.joins(:type_script).where(type_script: { script_hash: }).take
[item&.token_id, item&.collection&.name]
end

def cota_info(transaction, address_id)
info = Array.new
process_transfer = ->(item, count) {
collection = item.collection
info << CkbUtils.hash_value_to_s({
collection_name: collection.name,
count:,
token_id: item.token_id,
})
info << CkbUtils.hash_value_to_s(
{
name: collection.name,
count:,
token_id: item.token_id,
},
)
}

transaction.token_transfers.each do |t|
Expand Down

0 comments on commit e8adc3a

Please sign in to comment.