diff --git a/app/controllers/api/v1/address_transactions_controller.rb b/app/controllers/api/v1/address_transactions_controller.rb index fd41ea4d0..ba158c68e 100644 --- a/app/controllers/api/v1/address_transactions_controller.rb +++ b/app/controllers/api/v1/address_transactions_controller.rb @@ -10,8 +10,29 @@ def show @address = Address.find_address!(params[:id]) raise Api::V1::Exceptions::AddressNotFoundError if @address.is_a?(NullAddress) - @tx_ids = AccountBook.where(address_id: @address.id).order("ckb_transaction_id" => :desc).select("ckb_transaction_id").page(@page).per(@page_size).fast_page - @ckb_transactions = CkbTransaction.tx_committed.where(id: @tx_ids.map(&:ckb_transaction_id)).select(:id, :tx_hash, :block_id, :block_number, :block_timestamp, :is_cellbase, :updated_at).order(id: :desc) + @tx_ids = AccountBook + .joins(:ckb_transaction) + .where(address_id: @address.id) + + params[:sort] ||= "ckb_transaction_id.desc" + order_by, asc_or_desc = params[:sort].split('.', 2) + order_by = case order_by + when 'time' then 'ckb_transactions.block_timestamp' + else order_by + end + + head :not_found and return unless order_by.in? %w[ckb_transaction_id block_timestamp ckb_transactions.block_timestamp] + + @tx_ids = @tx_ids + .order(order_by => asc_or_desc) + .select("ckb_transaction_id") + .page(@page).per(@page_size).fast_page + + order_by = 'id' if order_by == 'ckb_transaction_id' + @ckb_transactions = CkbTransaction.tx_committed.where(id: @tx_ids.map(&:ckb_transaction_id)) + .select(:id, :tx_hash, :block_id, :block_number, :block_timestamp, :is_cellbase, :updated_at, :capacity_involved) + .order(order_by => asc_or_desc) + json = Rails.cache.realize("#{@ckb_transactions.cache_key}/#{@address.query_address}", version: @ckb_transactions.cache_version) do @options = FastJsonapi::PaginationMetaGenerator.new(request: request, records: @ckb_transactions, page: @page, page_size: @page_size, records_counter: @tx_ids).call diff --git a/app/controllers/api/v1/block_transactions_controller.rb b/app/controllers/api/v1/block_transactions_controller.rb index b637a693c..6c1162a9b 100644 --- a/app/controllers/api/v1/block_transactions_controller.rb +++ b/app/controllers/api/v1/block_transactions_controller.rb @@ -6,13 +6,17 @@ class BlockTransactionsController < ApplicationController include Pagy::Backend def show block = Block.find_by!(block_hash: params[:id]) + temp_transactions = block.ckb_transactions + .select(:id, :tx_hash, :block_id, :block_number, :block_timestamp, :is_cellbase, :updated_at) + .where(block_timestamp: block.timestamp) + temp_transactions = temp_transactions.where(tx_hash: params[:tx_hash]) if params[:tx_hash].present? + temp_transactions = temp_transactions.order(id: :desc) + @pagy, ckb_transactions = pagy( - block.ckb_transactions - .select(:id, :tx_hash, :block_id, :block_number, :block_timestamp, :is_cellbase, :updated_at) - .where(block_timestamp: block.timestamp) - .order(:id), + temp_transactions, items: params[:page_size] || 10, - overflow: :empty_page) + overflow: :empty_page + ) json = Rails.cache.realize(ckb_transactions.cache_key, version: ckb_transactions.cache_version) do diff --git a/app/controllers/api/v1/blocks_controller.rb b/app/controllers/api/v1/blocks_controller.rb index ff09ae532..0a42d0c4d 100644 --- a/app/controllers/api/v1/blocks_controller.rb +++ b/app/controllers/api/v1/blocks_controller.rb @@ -13,7 +13,19 @@ def index BlockListSerializer.new(blocks).serialized_json end else - blocks = Block.recent.select(:id, :miner_hash, :number, :timestamp, :reward, :ckb_transactions_count, :live_cell_changes, :updated_at).page(@page).per(@page_size).fast_page + blocks = Block.select(:id, :miner_hash, :number, :timestamp, :reward, :ckb_transactions_count, :live_cell_changes, :updated_at) + params[:sort] ||= "timestamp.desc" + + order_by, asc_or_desc = params[:sort].split('.', 2) + order_by = case order_by + when 'height' then 'number' + when 'transactions' then 'ckb_transactions_count' + else order_by + end + + head :not_found and return unless order_by.in? %w[number reward timestamp ckb_transactions_count] + blocks = blocks.order(order_by => asc_or_desc).page(@page).per(@page_size).fast_page + json = Rails.cache.realize(blocks.cache_key, version: blocks.cache_version, race_condition_ttl: 3.seconds) do records_counter = RecordCounters::Blocks.new diff --git a/app/controllers/api/v1/ckb_transactions_controller.rb b/app/controllers/api/v1/ckb_transactions_controller.rb index da2f07ce3..34dcf25da 100644 --- a/app/controllers/api/v1/ckb_transactions_controller.rb +++ b/app/controllers/api/v1/ckb_transactions_controller.rb @@ -17,9 +17,24 @@ def index end render json: json else - ckb_transactions = CkbTransaction.tx_committed.recent.normal.select( + ckb_transactions = CkbTransaction.normal.select( :id, :tx_hash, :block_number, :block_timestamp, :live_cell_changes, :capacity_involved, :updated_at - ).page(@page).per(@page_size).fast_page + ) + + params[:sort] ||= "id.desc" + + order_by, asc_or_desc = params[:sort].split('.', 2) + order_by = case order_by + when 'height' then 'block_number' + when 'capacity' then 'capacity_involved' + else order_by + end + + head :not_found and return unless order_by.in? %w[id block_number block_timestamp transaction_fee capacity_involved] + + ckb_transactions = ckb_transactions.order(order_by => asc_or_desc) + .page(@page).per(@page_size).fast_page + json = Rails.cache.realize(ckb_transactions.cache_key, version: ckb_transactions.cache_version, race_condition_ttl: 3.seconds) do diff --git a/app/controllers/api/v1/contract_transactions_controller.rb b/app/controllers/api/v1/contract_transactions_controller.rb index 7ab69e7e3..bfb079dec 100644 --- a/app/controllers/api/v1/contract_transactions_controller.rb +++ b/app/controllers/api/v1/contract_transactions_controller.rb @@ -7,7 +7,12 @@ def show raise Api::V1::Exceptions::ContractNotFoundError if params[:id] != DaoContract::CONTRACT_NAME dao_contract = DaoContract.default_contract - ckb_transactions = dao_contract.ckb_transactions.includes(:cell_inputs, :cell_outputs).tx_committed.select(:id, :tx_hash, :block_id, :block_number, :block_timestamp, :is_cellbase, :updated_at).recent.page(@page).per(@page_size).fast_page + ckb_transactions = dao_contract.ckb_transactions.includes(:cell_inputs, :cell_outputs).tx_committed + .select(:id, :tx_hash, :block_id, :block_number, :block_timestamp, :is_cellbase, :updated_at).recent + + ckb_transactions = ckb_transactions.where(tx_hash: params[:tx_hash]) if params[:tx_hash].present? + ckb_transactions = ckb_transactions + .page(@page).per(@page_size).fast_page json = Rails.cache.realize(ckb_transactions.cache_key, version: ckb_transactions.cache_version) do records_counter = RecordCounters::DaoTransactions.new(dao_contract) diff --git a/app/controllers/api/v1/udt_transactions_controller.rb b/app/controllers/api/v1/udt_transactions_controller.rb index 480ce56f5..9fef60888 100644 --- a/app/controllers/api/v1/udt_transactions_controller.rb +++ b/app/controllers/api/v1/udt_transactions_controller.rb @@ -6,7 +6,14 @@ class UdtTransactionsController < ApplicationController def show udt = Udt.find_by!(type_hash: params[:id], published: true) - ckb_transactions = udt.ckb_transactions.tx_committed.select(:id, :tx_hash, :block_id, :block_number, :block_timestamp, :is_cellbase, :updated_at).recent.page(@page).per(@page_size).fast_page + ckb_transactions = udt.ckb_transactions.tx_committed + .select(:id, :tx_hash, :block_id, :block_number, :block_timestamp, :is_cellbase, :updated_at).recent + + # TODO minted? burn? transfer? + ckb_transactions = ckb_transactions.where(tx_hash: params[:tx_hash]) if params[:tx_hash].present? + ckb_transactions = ckb_transactions + .page(@page).per(@page_size).fast_page + json = Rails.cache.realize("#{udt.symbol}/#{ckb_transactions.cache_key}", version: ckb_transactions.cache_version) do records_counter = RecordCounters::UdtTransactions.new(udt) diff --git a/app/controllers/api/v1/udts_controller.rb b/app/controllers/api/v1/udts_controller.rb index 7d88e03aa..f2cea54dd 100644 --- a/app/controllers/api/v1/udts_controller.rb +++ b/app/controllers/api/v1/udts_controller.rb @@ -4,7 +4,24 @@ class Api::V1::UdtsController < ApplicationController before_action :validate_pagination_params, :pagination_params, only: :index def index - udts = Udt.sudt.order(addresses_count: :desc, id: :asc).page(@page).per(@page_size).fast_page + udts = Udt.sudt + + params[:sort] ||= "id.desc" + + order_by, asc_or_desc = params[:sort].split('.', 2) + order_by = case order_by + when 'created_time' then 'block_timestamp' + # current we don't support this in DB + # need a new PR https://github.com/nervosnetwork/ckb-explorer/pull/1266/ + # when 'transactions' then 'h24_ckb_transactions_count' + else order_by + end + + head :not_found and return unless order_by.in? %w[id addresses_count block_timestamp] + + udts = udts.order(order_by => asc_or_desc) + .page(@page).per(@page_size).fast_page + options = FastJsonapi::PaginationMetaGenerator.new(request: request, records: udts, page: @page, page_size: @page_size).call render json: UdtSerializer.new(udts, options) end diff --git a/app/controllers/api/v2/nft/collections_controller.rb b/app/controllers/api/v2/nft/collections_controller.rb index cadc93a24..ee6660a33 100644 --- a/app/controllers/api/v2/nft/collections_controller.rb +++ b/app/controllers/api/v2/nft/collections_controller.rb @@ -2,10 +2,29 @@ module Api module V2 class NFT::CollectionsController < BaseController def index - pagy, collections = pagy(TokenCollection.order(id: :desc)) + params[:sort] ||= "id.desc" + + order_by, asc_or_desc = params[:sort].split('.', 2) + order_by = case order_by + # TODO need to merge PR: https://github.com/nervosnetwork/ckb-explorer/pull/1266 + when 'transactions' then 'h24_transactions_count' + when 'holder' then 'holders_count' + when 'minted' then 'items_count' + else order_by + end + + head :not_found and return unless order_by.in? %w[id holders_count items_count] + + collections = TokenCollection + collections = collections.where(standard: params[:type]) if params[:type].present? + collections = collections + .order(order_by => asc_or_desc) + .page(@page).per(@page_size).fast_page + + @pagy, @collections = pagy(collections) render json: { - data: collections, - pagination: pagy_metadata(pagy) + data: @collections, + pagination: pagy_metadata(@pagy) } end diff --git a/app/controllers/api/v2/pending_transactions_controller.rb b/app/controllers/api/v2/pending_transactions_controller.rb index ccfe6956e..8b3dd5bde 100644 --- a/app/controllers/api/v2/pending_transactions_controller.rb +++ b/app/controllers/api/v2/pending_transactions_controller.rb @@ -2,8 +2,22 @@ module Api::V2 class PendingTransactionsController < BaseController before_action :set_page_and_page_size def index - pending_transactions = PoolTransactionEntry.pool_transaction_pending.order('id desc').page(@page).per(@page_size).fast_page - head :not_found and return if pending_transactions.blank? + pending_transactions = PoolTransactionEntry.pool_transaction_pending + + params[:sort] ||= "id.desc" + order_by, asc_or_desc = params[:sort].split('.', 2) + order_by = case order_by + when 'time' then 'created_at' + when 'fee' then 'transaction_fee' + # current we don't support this in DB + #when 'capacity' then 'capacity_involved' + else order_by + end + + head :not_found and return unless order_by.in? %w[id created_at transaction_fee] + + pending_transactions = pending_transactions.order(order_by => asc_or_desc) + .page(@page).per(@page_size).fast_page render json: { data: pending_transactions.map {|tx| diff --git a/test/controllers/api/v1/block_transactions_controller_test.rb b/test/controllers/api/v1/block_transactions_controller_test.rb index 7b6c48377..f06d92399 100644 --- a/test/controllers/api/v1/block_transactions_controller_test.rb +++ b/test/controllers/api/v1/block_transactions_controller_test.rb @@ -80,7 +80,7 @@ class BlockTransactionsControllerTest < ActionDispatch::IntegrationTest valid_get api_v1_block_transaction_url(block.block_hash) - ckb_transactions = block.ckb_transactions.order(:id).page(page).per(page_size) + ckb_transactions = block.ckb_transactions.order('id desc').page(page).per(page_size) records_counter = RecordCounters::BlockTransactions.new(block) options = FastJsonapi::PaginationMetaGenerator.new(request: request, records: ckb_transactions, page: page, page_size: page_size, records_counter: records_counter).call @@ -157,7 +157,7 @@ class BlockTransactionsControllerTest < ActionDispatch::IntegrationTest page = 2 page_size = 10 block = create(:block, :with_ckb_transactions, transactions_count: 30) - block_ckb_transactions = block.ckb_transactions.order(:id).page(page).per(page_size) + block_ckb_transactions = block.ckb_transactions.order('id desc').page(page).per(page_size) valid_get api_v1_block_transaction_url(block.block_hash), params: { page: page } @@ -173,7 +173,7 @@ class BlockTransactionsControllerTest < ActionDispatch::IntegrationTest page = 1 page_size = 12 block = create(:block, :with_ckb_transactions, transactions_count: 15) - block_ckb_transactions = block.ckb_transactions.order(:id).page(page).per(page_size) + block_ckb_transactions = block.ckb_transactions.order('id desc').page(page).per(page_size) valid_get api_v1_block_transaction_url(block.block_hash), params: { page_size: page_size } @@ -186,10 +186,11 @@ class BlockTransactionsControllerTest < ActionDispatch::IntegrationTest end test "should return the corresponding transactions when page and page_size are set" do + CkbTransaction.delete_all page = 2 page_size = 5 block = create(:block, :with_ckb_transactions, transactions_count: 30) - block_ckb_transactions = block.ckb_transactions.order(:id).page(page).per(page_size) + block_ckb_transactions = block.ckb_transactions.order('id desc').page(page).per(page_size) valid_get api_v1_block_transaction_url(block.block_hash), params: { page: page, page_size: page_size } @@ -204,7 +205,7 @@ class BlockTransactionsControllerTest < ActionDispatch::IntegrationTest page = 2 page_size = 5 block = create(:block) - block_ckb_transactions = block.ckb_transactions.order(:id).page(page).per(page_size) + block_ckb_transactions = block.ckb_transactions.order('id desc').page(page).per(page_size) valid_get api_v1_block_transaction_url(block.block_hash), params: { page: page, page_size: page_size }