Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ def show
address = Address.find_address!(params[:id])
raise Api::V1::Exceptions::AddressNotFoundError if address.is_a?(NullAddress)

includes = { :cell_inputs => {:previous_cell_output => {:type_script => [], :bitcoin_vout => [], :lock_script => [] }, :block => []}, :cell_outputs => {}, :bitcoin_annotation => [], :account_books => {} }
includes = { bitcoin_annotation: [],
cell_outputs: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script],
cell_inputs: [:block, previous_cell_output: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script]]}

ckb_dao_transactions = address.ckb_dao_transactions
.includes(includes)
.select(select_fields)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ def show
udt = Udt.find_by(type_hash: params[:type_hash], published: true)
raise Api::V1::Exceptions::UdtNotFoundError if udt.blank?

includes = { :cell_inputs => {:previous_cell_output => {:type_script => [], :bitcoin_vout => [], :lock_script => [] }, :block => []}, :cell_outputs => {}, :bitcoin_annotation => [], :account_books => {} }
includes = { bitcoin_annotation: [],
cell_outputs: [:address, :deployed_contract, :udt_cell, :type_script, :bitcoin_vout, :lock_script],
cell_inputs: [:block, previous_cell_output: [:udt_cell, :address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script]]}

ckb_udt_transactions = address.ckb_udt_transactions(udt.id)
.includes(includes)
.select(select_fields)
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/api/v1/block_transactions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ def show
where(account_books: { address_id: address.id })
end

includes = { :cell_inputs => {:previous_cell_output => {:type_script => [], :bitcoin_vout => [], :lock_script => [] }, :block => []}, :cell_outputs => {}, :bitcoin_annotation => [], :account_books => {} }
includes = { bitcoin_annotation: [],
cell_outputs: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script],
cell_inputs: [:block, previous_cell_output: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script]]}

if stale?(ckb_transactions)
expires_in 10.seconds, public: true, must_revalidate: true, stale_while_revalidate: 5.seconds
Expand Down
15 changes: 13 additions & 2 deletions app/controllers/api/v1/ckb_transactions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ def query
CkbTransaction.recent.normal.page(@page).per(@page_size).fast_page
end

includes = { :cell_inputs => {:previous_cell_output => {:type_script => [], :bitcoin_vout => [], :lock_script => [] }, :block => []}, :cell_outputs => {}, :bitcoin_annotation => [], :account_books => {} }
includes = { bitcoin_annotation: [],
cell_outputs: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script],
cell_inputs: [:block, previous_cell_output: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script]]}

ckb_transactions = ckb_transactions.includes(includes).select(:id, :tx_hash, :block_id, :tags,
:block_number, :block_timestamp, :is_cellbase, :updated_at, :created_at)
json =
Expand Down Expand Up @@ -139,7 +142,15 @@ def validate_query_params
end

def find_transaction
@ckb_transaction = CkbTransaction.where(tx_hash: params[:id]).order(tx_status: :asc).first

includes = { bitcoin_annotation: [],
witnesses: [],
block: [:epoch_statistic],
cell_dependencies: [:cell_output, :contract],
cell_outputs: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script],
cell_inputs: [:block, previous_cell_output: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script]]}

@ckb_transaction = CkbTransaction.includes(includes).where(tx_hash: params[:id]).first
raise Api::V1::Exceptions::CkbTransactionNotFoundError if @ckb_transaction.blank?
end
end
Expand Down
6 changes: 4 additions & 2 deletions app/controllers/api/v1/contract_transactions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def show
if stale?(dao_contract)
expires_in 10.seconds, public: true, must_revalidate: true, stale_while_revalidate: 5.seconds

ckb_transactions = dao_contract.ckb_transactions.includes(:cell_inputs, :cell_outputs).tx_committed.order("ckb_transactions.block_timestamp desc nulls last, ckb_transactions.id desc")
ckb_transactions = dao_contract.ckb_transactions.tx_committed.order("ckb_transactions.block_timestamp desc nulls last, ckb_transactions.id desc")

if params[:tx_hash].present?
ckb_transactions = ckb_transactions.where(tx_hash: params[:tx_hash])
Expand All @@ -25,7 +25,9 @@ def show
where(account_books: { address_id: address.id })
end

includes = { :cell_inputs => {:previous_cell_output => {:type_script => [], :bitcoin_vout => [], :lock_script => [] }, :block => []}, :cell_outputs => {}, :bitcoin_annotation => [], :account_books => {} }
includes = { bitcoin_annotation: [],
cell_outputs: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script],
cell_inputs: [:block, previous_cell_output: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script]]}

ckb_transactions = ckb_transactions
.includes(includes)
Expand Down
12 changes: 10 additions & 2 deletions app/interactions/addresses/ckb_transactions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,16 @@ def execute

ckb_transaction_ids = account_books.map(&:ckb_transaction_id)

includes = { :cell_inputs => {:previous_cell_output => {:type_script => [], :bitcoin_vout => [], :lock_script => [] }, :block => []}, :cell_outputs => {}, :bitcoin_annotation => [], :account_books => {} }
includes[:bitcoin_transfers] = {} if is_bitcoin
includes = if is_bitcoin
{ bitcoin_annotation: [],
bitcoin_transfers: [:bitcoin_transaction],
cell_outputs: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script, bitcoin_vout: [:bitcoin_address, :bitcoin_transaction]],
cell_inputs: [:block, previous_cell_output: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script, bitcoin_vout: [:bitcoin_address, :bitcoin_transaction]]]}
else
{ bitcoin_annotation: [],
cell_outputs: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script],
cell_inputs: [:block, previous_cell_output: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script]]}
end

records = CkbTransaction.where(id: ckb_transaction_ids)
.includes(includes)
Expand Down
4 changes: 2 additions & 2 deletions app/interactions/addresses/live_cells.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ def fetch_cell_output_scope(address)
scope =
if bound_status
vout_ids = BitcoinVout.where(address_id: address_ids, status: bound_status).pluck(:cell_output_id)
CellOutput.live.includes(:type_script, :lock_script).where(id: vout_ids)
CellOutput.live.includes(:type_script, :lock_script, :block).where(id: vout_ids)
else
CellOutput.live.includes(:type_script, :lock_script).where(address_id: address_ids)
CellOutput.live.includes(:type_script, :lock_script, :block).where(address_id: address_ids)
end

tag.present? ? filter_by_tag(scope) : scope
Expand Down
4 changes: 3 additions & 1 deletion app/interactions/udts/ckb_transactions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ def execute
where(account_books: { address_id: address.map(&:id) }).distinct
end

includes = { :cell_inputs => {:previous_cell_output => {:type_script => [], :bitcoin_vout => [], :lock_script => [] }, :block => []}, :cell_outputs => {}, :bitcoin_annotation => [], :account_books => {} }
includes = { bitcoin_annotation: [],
cell_outputs: [:address, :deployed_contract, :udt_cell, :type_script, :bitcoin_vout, :lock_script],
cell_inputs: [:block, previous_cell_output: [:address, :udt_cell, :deployed_contract, :type_script, :bitcoin_vout, :lock_script]]}

records = ckb_transactions
.includes(includes)
Expand Down
2 changes: 1 addition & 1 deletion app/models/cell_dependency.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ class CellDependency < ApplicationRecord
belongs_to :cell_output, foreign_key: "contract_cell_id", class_name: "CellOutput"
has_many :cell_deps_out_points, foreign_key: :contract_cell_id, primary_key: :contract_cell_id, class_name: "CellDepsOutPoint"
has_many :contracts, foreign_key: :contract_cell_id, primary_key: :contract_cell_id, class_name: "Contract"
has_one :contract, -> { where(is_primary: true) }, foreign_key: :contract_cell_id, primary_key: :contract_cell_id, class_name: "Contract"

enum :dep_type, %i[code dep_group]

def to_raw
contract = contracts.primary.first
script =
if contract
{
Expand Down
2 changes: 2 additions & 0 deletions app/models/cell_output.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class CellOutput < ApplicationRecord
belongs_to :address
belongs_to :lock_script
belongs_to :type_script, optional: true
has_one :deployed_contract, foreign_key: :deployed_cell_output_id, class_name: "Contract"
belongs_to :udt_cell, ->(c) { where(published: true) }, foreign_key: :type_hash, class_name: 'Udt', optional: true

has_many :cell_dependencies, foreign_key: :contract_cell_id,
dependent: :delete_all
Expand Down
4 changes: 2 additions & 2 deletions app/models/concerns/cell_outputs/extra_info.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module ExtraInfo
def udt_info
return unless cell_type.in?(%w(udt xudt xudt_compatible ssri))

udt_info = Udt.find_by(type_hash:, published: true)
udt_info = udt_cell
CkbUtils.hash_value_to_s(
symbol: udt_info&.symbol,
amount: udt_amount,
Expand Down Expand Up @@ -190,7 +190,7 @@ def rgb_info
def tags
tags = []
tags << "fiber" if lock_script.code_hash == Settings.fiber_funding_code_hash
tags << "deployment" if Contract.exists?(deployed_cell_output_id: id)
tags << "deployment" if deployed_contract
tags << "multisig" if
(lock_script.code_hash == Settings.multisig_code_hash && lock_script.hash_type == "data1") ||
(lock_script.code_hash == Settings.secp_multisig_cell_type_hash && lock_script.hash_type == "type")
Expand Down
2 changes: 1 addition & 1 deletion app/models/concerns/ckb_transactions/bitcoin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def btc_time_transaction?
def rgb_txid
return if !rgb_transaction? && !btc_time_transaction?

transfer = bitcoin_transfers.order(lock_type: :asc).first
transfer = bitcoin_transfers.sort_by(&:lock_type).first
transfer&.bitcoin_transaction&.txid
end

Expand Down
23 changes: 13 additions & 10 deletions app/models/concerns/ckb_transactions/display_cells.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ def normal_tx_display_inputs(cell_inputs_for_display)
display_input.merge!(attributes_for_dao_input(previous_cell_output))
end
if previous_cell_output.nervos_dao_deposit?
display_input.merge!(attributes_for_dao_input(cell_outputs.sort_by(&:cell_index)[cell_input.index], false))
nervos_dao_withdrawing_cell = cell_outputs.sort_by(&:cell_index)[cell_input.index]
compensation_started_block = cell_input.block
display_input.merge!(attributes_for_dao_input(nervos_dao_withdrawing_cell, compensation_started_block, false))
end
if previous_cell_output.udt?
display_input.merge!(attributes_for_udt_cell(previous_cell_output))
Expand Down Expand Up @@ -217,13 +219,15 @@ def attributes_for_omiga_inscription_cell(omiga_inscription_cell)
{ omiga_inscription_info: info, extra_info: info }
end

def attributes_for_dao_input(nervos_dao_withdrawing_cell, is_phase2 = true)
block_number = CKB::Utils.hex_to_bin(nervos_dao_withdrawing_cell.data).unpack("Q<").pack("Q>").unpack1("H*").hex
# start block: the block contains the transaction which generated the deposit cell output
compensation_started_block = Block.select(:number, :timestamp).find_by_number(block_number)
def attributes_for_dao_input(nervos_dao_withdrawing_cell, compensation_started_block = nil, is_phase2 = true)
unless compensation_started_block
started_block_number = CKB::Utils.hex_to_bin(nervos_dao_withdrawing_cell.data).unpack("Q<").pack("Q>").unpack1("H*").hex
# start block: the block contains the transaction which generated the deposit cell output
compensation_started_block = Block.find_by_number(started_block_number)
end
# end block: the block contains the transaction which generated the withdrawing cell
compensation_ended_block = Block.select(:number, :timestamp).find(nervos_dao_withdrawing_cell.block_id)
interest = CkbUtils.dao_interest(nervos_dao_withdrawing_cell)
compensation_ended_block = nervos_dao_withdrawing_cell.block
interest = CkbUtils.dao_interest(nervos_dao_withdrawing_cell, compensation_started_block.dao)

attributes = {
compensation_started_block_number: compensation_started_block.number,
Expand All @@ -234,9 +238,8 @@ def attributes_for_dao_input(nervos_dao_withdrawing_cell, is_phase2 = true)
}

if is_phase2
number, timestamp = Block.where(id: block_id).pick(:number, :timestamp) # locked_until_block
attributes[:locked_until_block_number] = number
attributes[:locked_until_block_timestamp] = timestamp
attributes[:locked_until_block_number] = block_number
attributes[:locked_until_block_timestamp] = block_timestamp
end

CkbUtils.hash_value_to_s(attributes)
Expand Down
2 changes: 1 addition & 1 deletion app/serializers/address_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class AddressSerializer
end
attribute :udt_accounts do |object|
if object.udt_accounts.present?
object.udt_accounts.published.map do |udt_account|
object.udt_accounts.find_all{|u| u.published }.map do |udt_account|
if udt_account.udt_type == "sudt"
{
symbol: udt_account.symbol,
Expand Down
4 changes: 2 additions & 2 deletions app/serializers/ckb_transaction_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ class CkbTransactionSerializer
attributes :is_cellbase, :tx_status

attribute :witnesses do |o|
o.witnesses.order("index ASC")&.map(&:data) || []
o.witnesses.sort_by(&:index)&.map(&:data) || []
end

attribute :cell_deps do |o|
o.cell_dependencies.order("id asc").includes(:cell_output, :contracts).to_a.map(&:to_raw)
o.cell_dependencies.sort_by(&:id).map(&:to_raw)
end

attribute :header_deps do |o|
Expand Down
8 changes: 5 additions & 3 deletions app/utils/ckb_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,11 @@ def self.dao_withdraw_tx_fee(ckb_transaction, tx_previous_outputs)
tx_previous_outputs.sum(&:capacity) + interests - CellOutput.where(ckb_transaction: ckb_transaction["id"]).sum(:capacity)
end

def self.dao_interest(nervos_dao_withdrawing_cell)
block_number = CKB::Utils.hex_to_bin(nervos_dao_withdrawing_cell.data).unpack("Q<").pack("Q>").unpack1("H*").hex
deposit_dao = Block.find_by_number(block_number).dao
def self.dao_interest(nervos_dao_withdrawing_cell, deposit_dao = nil)
unless deposit_dao
block_number = CKB::Utils.hex_to_bin(nervos_dao_withdrawing_cell.data).unpack("Q<").pack("Q>").unpack1("H*").hex
deposit_dao = Block.find_by_number(block_number).dao
end
withdrawing_dao_cell_block_dao = nervos_dao_withdrawing_cell.dao
DaoCompensationCalculator.new(nil, withdrawing_dao_cell_block_dao,
nervos_dao_withdrawing_cell, deposit_dao).call
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class AddressDaoTransactionsControllerTest < ActionDispatch::IntegrationTest
address = create(:address, :with_transactions)
fake_dao_deposit_transaction(3, address)
ckb_dao_transactions = address.ckb_dao_transactions.recent.page(page).per(page_size)

valid_get api_v1_address_dao_transaction_url(address.address_hash)

options = FastJsonapi::PaginationMetaGenerator.new(request:, records: ckb_dao_transactions, page:, page_size:).call
Expand Down
1 change: 1 addition & 0 deletions test/controllers/api/v1/addresses_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ class AddressesControllerTest < ActionDispatch::IntegrationTest
udt_account = create(:udt_account, symbol: udt.symbol, full_name: udt.full_name, decimal: udt.decimal, published: true, address:, udt_id: udt.id,
udt_type: "omiga_inscription", type_hash: udt.type_hash, amount: info.mint_limit)
address.query_address = address.address_hash

valid_get api_v1_address_url(address.address_hash)
assert_equal [
{
Expand Down
6 changes: 4 additions & 2 deletions test/models/ckb_transaction_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ class CkbTransactionTest < ActiveSupport::TestCase
compensation_ended_block_number compensation_started_timestamp compensation_ended_timestamp
interest cell_type cell_index since locked_until_block_number locked_until_block_timestamp tags type_script
).sort

ckb_transaction = CkbTransaction.includes(:bitcoin_annotation, :account_books, cell_outputs: [:address, :deployed_contract], cell_inputs: [:block, previous_cell_output: [:address, :deployed_contract, :type_script, :bitcoin_vout, :lock_script]]).find(ckb_transaction.id)
display_inputs = ckb_transaction.display_inputs
assert_equal expected_attributes, display_inputs.first.keys.sort
assert_equal expected_display_input, display_inputs.first.sort
Expand Down Expand Up @@ -277,9 +279,9 @@ class CkbTransactionTest < ActiveSupport::TestCase
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,
compensation_started_block_number: ckb_transaction.block_number,
compensation_ended_block_number: ended_block.number,
compensation_started_timestamp: started_block.timestamp,
compensation_started_timestamp: ckb_transaction.block_timestamp,
compensation_ended_timestamp: ended_block.timestamp,
interest:,
cell_type: deposit_output_cell.cell_type,
Expand Down
Loading