diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e1326654..62763f902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# [v0.9.7](https://github.com/shaojunda/ckb-explorer/compare/v0.9.6...v0.9.7) (2020-06-05) + + +### Features + +* #[635](https://github.com/nervosnetwork/ckb-explorer/pull/635): add udts api + + +### Performance Improvements + +* #[625](https://github.com/nervosnetwork/ckb-explorer/pull/625): address dao and udt transactions api + + # [v0.9.6](https://github.com/shaojunda/ckb-explorer/compare/v0.9.5...v0.9.6) (2020-06-01) diff --git a/app/controllers/api/v1/address_dao_transactions_controller.rb b/app/controllers/api/v1/address_dao_transactions_controller.rb index f6a88cabc..634dab64a 100644 --- a/app/controllers/api/v1/address_dao_transactions_controller.rb +++ b/app/controllers/api/v1/address_dao_transactions_controller.rb @@ -8,8 +8,7 @@ def show address = Address.find_address!(params[:id]) raise Api::V1::Exceptions::AddressNotFoundError if address.is_a?(NullAddress) - presented_address = AddressPresenter.new(address) - ckb_dao_transactions = presented_address.ckb_dao_transactions.recent.distinct.page(@page).per(@page_size) + ckb_dao_transactions = address.ckb_dao_transactions.recent.page(@page).per(@page_size) options = FastJsonapi::PaginationMetaGenerator.new(request: request, records: ckb_dao_transactions, page: @page, page_size: @page_size).call render json: CkbTransactionSerializer.new(ckb_dao_transactions, options.merge({ params: { previews: true } })) diff --git a/app/controllers/api/v1/address_transactions_controller.rb b/app/controllers/api/v1/address_transactions_controller.rb index 482829afd..ac8113d3c 100644 --- a/app/controllers/api/v1/address_transactions_controller.rb +++ b/app/controllers/api/v1/address_transactions_controller.rb @@ -8,8 +8,7 @@ def show @address = Address.find_address!(params[:id]) raise Api::V1::Exceptions::AddressNotFoundError if @address.is_a?(NullAddress) - presented_address = AddressPresenter.new(@address) - @ckb_transactions = presented_address.ckb_transactions.recent.distinct.page(@page).per(@page_size) + @ckb_transactions = @address.custom_ckb_transactions.recent.page(@page).per(@page_size) @options = FastJsonapi::PaginationMetaGenerator.new(request: request, records: @ckb_transactions, page: @page, page_size: @page_size).call render json: json_result diff --git a/app/controllers/api/v1/address_udt_transactions_controller.rb b/app/controllers/api/v1/address_udt_transactions_controller.rb index 3f35d962b..28830feef 100644 --- a/app/controllers/api/v1/address_udt_transactions_controller.rb +++ b/app/controllers/api/v1/address_udt_transactions_controller.rb @@ -12,8 +12,7 @@ def show udt = Udt.find_by(type_hash: params[:type_hash], published: true) raise Api::V1::Exceptions::UdtNotFoundError if udt.blank? - presented_address = AddressPresenter.new(address) - ckb_dao_transactions = presented_address.ckb_udt_transactions(params[:type_hash]).recent.distinct.page(@page).per(@page_size) + ckb_dao_transactions = address.ckb_udt_transactions(params[:type_hash]).recent.page(@page).per(@page_size) options = FastJsonapi::PaginationMetaGenerator.new(request: request, records: ckb_dao_transactions, page: @page, page_size: @page_size).call render json: CkbTransactionSerializer.new(ckb_dao_transactions, options.merge({ params: { previews: true } })) diff --git a/app/controllers/api/v1/addresses_controller.rb b/app/controllers/api/v1/addresses_controller.rb index 46414ad90..851ce7637 100644 --- a/app/controllers/api/v1/addresses_controller.rb +++ b/app/controllers/api/v1/addresses_controller.rb @@ -26,7 +26,7 @@ def json_response(address) if QueryKeyUtils.valid_hex?(params[:id]) LockHashSerializer.new(address) else - presented_address = address.is_a?(NullAddress) ? NullAddress.new(params[:id]) : AddressPresenter.new(address) + presented_address = address.is_a?(NullAddress) ? NullAddress.new(params[:id]) : address AddressSerializer.new(presented_address) end end diff --git a/app/controllers/api/v1/udt_transactions_controller.rb b/app/controllers/api/v1/udt_transactions_controller.rb index a31928b2a..f3f6fab1d 100644 --- a/app/controllers/api/v1/udt_transactions_controller.rb +++ b/app/controllers/api/v1/udt_transactions_controller.rb @@ -4,7 +4,7 @@ class Api::V1::UdtTransactionsController < ApplicationController def show udt = Udt.find_by!(type_hash: params[:id], published: true) - ckb_transactions = udt.ckb_transactions.recent.distinct.page(@page).per(@page_size) + ckb_transactions = udt.ckb_transactions.recent.page(@page).per(@page_size) options = FastJsonapi::PaginationMetaGenerator.new(request: request, records: ckb_transactions, page: @page, page_size: @page_size).call render json: CkbTransactionSerializer.new(ckb_transactions, options.merge({ params: { previews: true } })) diff --git a/app/controllers/api/v1/udts_controller.rb b/app/controllers/api/v1/udts_controller.rb index 6b28451b5..8b259a22e 100644 --- a/app/controllers/api/v1/udts_controller.rb +++ b/app/controllers/api/v1/udts_controller.rb @@ -1,6 +1,11 @@ class Api::V1::UdtsController < ApplicationController before_action :validate_query_params, only: :show + def index + udts = Udt.order(addresses_count: :desc).limit(1000) + render json: UdtSerializer.new(udts) + end + def show udt = Udt.find_by!(type_hash: params[:id], published: true) diff --git a/app/controllers/validations/distribution_data.rb b/app/controllers/validations/distribution_data.rb index a6e55bcc6..3139643c3 100644 --- a/app/controllers/validations/distribution_data.rb +++ b/app/controllers/validations/distribution_data.rb @@ -25,9 +25,15 @@ def error_object attr_accessor :query_key def query_key_format_must_be_correct - if query_key.blank? || !(query_key.split("-") - ::DistributionData::VALID_INDICATORS).empty? + if query_key.blank? || !query_key_valid? errors.add(:query_key, "indicator name is invalid") end end + + def query_key_valid? + query_keys = query_key.split("-") + extra_keys = query_keys - ::DistributionData::VALID_INDICATORS + extra_keys.blank? || extra_keys.size == 1 && /^miner_address_distribution(\d+)$/ =~ extra_keys.first + end end end diff --git a/app/controllers/validations/monetary_data.rb b/app/controllers/validations/monetary_data.rb index bb1444249..1a1da42d6 100644 --- a/app/controllers/validations/monetary_data.rb +++ b/app/controllers/validations/monetary_data.rb @@ -33,7 +33,7 @@ def query_key_format_must_be_correct def query_key_valid? query_keys = query_key.split("-") extra_keys = query_keys - ::MonetaryData::VALID_INDICATORS - extra_keys.blank? || extra_keys.size == 1 && extra_keys.first =~ /^nominal_apc(\d+)$/ + extra_keys.blank? || extra_keys.size == 1 && /^nominal_apc(\d+)$/ =~ extra_keys.first end end end diff --git a/app/models/address.rb b/app/models/address.rb index 65c0cc9b0..f9b18be65 100644 --- a/app/models/address.rb +++ b/app/models/address.rb @@ -17,6 +17,53 @@ class Address < ApplicationRecord attr_accessor :query_address + def custom_ckb_transactions + ckb_transaction_ids = account_books.select(:ckb_transaction_id).distinct + CkbTransaction.where(id: ckb_transaction_ids) + end + + def ckb_dao_transactions + ckb_transaction_ids = cell_outputs.where(cell_type: %w(nervos_dao_deposit nervos_dao_withdrawing)).select("ckb_transaction_id").distinct + CkbTransaction.where(id: ckb_transaction_ids) + end + + def ckb_udt_transactions(type_hash) + sql = + <<-SQL + SELECT + generated_by_id ckb_transaction_id + FROM + cell_outputs + WHERE + address_id = #{id} + AND + cell_type = #{CellOutput::cell_types['udt']} + AND + type_hash = '#{type_hash}' + + UNION + + SELECT + consumed_by_id ckb_transaction_id + FROM + cell_outputs + WHERE + address_id = #{id} + AND + cell_type = #{CellOutput::cell_types['udt']} + AND + type_hash = '#{type_hash}' + AND + consumed_by_id is not null + SQL + ckb_transaction_ids = CellOutput.select("ckb_transaction_id").from("(#{sql}) as cell_outputs") + CkbTransaction.where(id: ckb_transaction_ids.distinct) + end + + def lock_info + lock_script.lock_info + end + def lock_script LockScript.where(address: self).first end diff --git a/app/models/ckb_sync/node_data_processor.rb b/app/models/ckb_sync/node_data_processor.rb index c90e64eb3..d045ac8e9 100644 --- a/app/models/ckb_sync/node_data_processor.rb +++ b/app/models/ckb_sync/node_data_processor.rb @@ -39,7 +39,7 @@ def process_block(node_block) update_current_block_mining_info(local_block) update_block_contained_address_info(local_block) update_block_reward_info(local_block) - update_udt_accounts(udt_infos) + update_udt_accounts(udt_infos, local_block.timestamp) update_udt_info(udt_infos) dao_events = build_new_dao_depositor_events(new_dao_depositor_events) DaoEvent.import!(dao_events, validate: false) @@ -67,7 +67,7 @@ def update_udt_info(udt_infos) Udt.import columns, import_values, validate: false, on_duplicate_key_update: { conflict_target: [:type_hash], columns: [:total_amount, :addresses_count] } end - def update_udt_accounts(udt_infos) + def update_udt_accounts(udt_infos, block_timestamp) return if udt_infos.blank? udt_infos.each do |udt_output| @@ -78,7 +78,7 @@ def update_udt_accounts(udt_infos) if udt_account.present? udt_account.update!(amount: amount) else - udt = Udt.find_or_create_by!(type_hash: udt_output[:type_hash], code_hash: ENV["SUDT_CELL_TYPE_HASH"], udt_type: "sudt") + udt = Udt.find_or_create_by!(type_hash: udt_output[:type_hash], code_hash: ENV["SUDT_CELL_TYPE_HASH"], udt_type: "sudt", block_timestamp: block_timestamp) address.udt_accounts.create!(udt_type: udt.udt_type, full_name: udt.full_name, symbol: udt.symbol, decimal: udt.decimal, published: udt.published, code_hash: udt.code_hash, type_hash: udt.type_hash, amount: amount, udt: udt) end end diff --git a/app/models/distribution_data.rb b/app/models/distribution_data.rb index f1e632250..9dd542653 100644 --- a/app/models/distribution_data.rb +++ b/app/models/distribution_data.rb @@ -77,11 +77,15 @@ def transaction_propagation_delay_history TransactionPropagationDelay.connection.select_all(sql) end - def miner_address_distribution - Rails.cache.realize("miner_address_distribution", expires_in: 1.day) do - result = Block.where("timestamp >= ?", CkbUtils.time_in_milliseconds(7.days.ago.to_i)).group(:miner_hash).order("count(miner_hash) desc").count.to_a + def miner_address_distribution(checkpoint = 7) + supported_checkpoints = [7, 90] + return unless checkpoint.in?(supported_checkpoints) + + Rails.cache.realize("miner_address_distribution_#{checkpoint}", expires_in: 1.day) do + result = Block.where("timestamp >= ?", CkbUtils.time_in_milliseconds(checkpoint.days.ago.to_i)).group(:miner_hash).order("count(miner_hash) desc").count.to_a + cut_off_point = (result.count * 0.7).floor if result.present? - (result[0..9].map{ |item| [item[0], item[1].to_s] } + [["other", result[10..-1].map { |item| item[1] }.reduce(:+).to_s]]).to_h + (result[0..cut_off_point].map{ |item| [item[0], item[1].to_s] } + [["other", result[(cut_off_point + 1)..-1].map { |item| item[1] }.reduce(:+).to_s]]).to_h else result end diff --git a/app/models/market_data.rb b/app/models/market_data.rb index 19a81d170..03ea03d86 100644 --- a/app/models/market_data.rb +++ b/app/models/market_data.rb @@ -102,7 +102,7 @@ def first_released_timestamp_may @first_released_timestamp_may ||= begin lock_address = Address.find_by(address_hash: "ckb1q3w9q60tppt7l3j7r09qcp7lxnp3vcanvgha8pmvsa3jplykxn323t90gna20lusyshreg32qee4fhkt9jj2t6qrqzzqxzq8yqt8kmd9") - lock_address.present? ? lock_address.lock_script.lock_info[:estimated_unlock_time].to_i : Time.find_zone("UTC").parse("2020-05-01").to_i + lock_address.present? ? lock_address.lock_script.lock_info[:estimated_unlock_time].to_i : CkbUtils.time_in_milliseconds(Time.find_zone("UTC").parse("2020-05-01")) end end @@ -111,7 +111,7 @@ def second_released_timestamp_may @second_released_timestamp_may ||= begin lock_address = Address.find_by(address_hash: "ckb1q3w9q60tppt7l3j7r09qcp7lxnp3vcanvgha8pmvsa3jplykxn323crn7nscet5sfwxjkzhexymfa4zntzt8vasvqzzqxzq8yq92pgkg") - lock_address.present? ? lock_address.lock_script.lock_info[:estimated_unlock_time].to_i : Time.find_zone("UTC").parse("2021-05-01").to_i + lock_address.present? ? lock_address.lock_script.lock_info[:estimated_unlock_time].to_i : CkbUtils.time_in_milliseconds(Time.find_zone("UTC").parse("2021-05-01")) end end @@ -120,7 +120,7 @@ def third_released_timestamp_may @third_released_timestamp_may ||= begin lock_address = Address.find_by(address_hash: "ckb1q3w9q60tppt7l3j7r09qcp7lxnp3vcanvgha8pmvsa3jplykxn32sl0qgva2l78fcnjt6x8kr8sln4lqs4twcpq4qzzqxzq8yq7hpadu") - lock_address.present? ? lock_address.lock_script.lock_info[:estimated_unlock_time].to_i : Time.find_zone("UTC").parse("2022-05-01").to_i + lock_address.present? ? lock_address.lock_script.lock_info[:estimated_unlock_time].to_i : CkbUtils.time_in_milliseconds(Time.find_zone("UTC").parse("2022-05-01")) end end @@ -129,7 +129,7 @@ def first_released_timestamp_other @first_released_timestamp_other ||= begin lock_address = Address.find_by(address_hash: "ckb1q3w9q60tppt7l3j7r09qcp7lxnp3vcanvgha8pmvsa3jplykxn32s3y29vjv73cfm8qax220dwwmpdccl4upy4s9qzzqxzq8yqyd09am") - lock_address.present? ? lock_address.lock_script.lock_info[:estimated_unlock_time].to_i : Time.find_zone("UTC").parse("2020-07-01").to_i + lock_address.present? ? lock_address.lock_script.lock_info[:estimated_unlock_time].to_i : CkbUtils.time_in_milliseconds(Time.find_zone("UTC").parse("2020-07-01")) end end @@ -138,7 +138,7 @@ def second_released_timestamp_other @second_released_timestamp_other ||= begin lock_address = Address.find_by(address_hash: "ckb1q3w9q60tppt7l3j7r09qcp7lxnp3vcanvgha8pmvsa3jplykxn32sn23uga5m8u5v87q98vr29qa8tl0ruu84gqfqzzqxzq8yqc2dxk6") - lock_address.present? ? lock_address.lock_script.lock_info[:estimated_unlock_time].to_i : Time.find_zone("UTC").parse("2020-12-31").to_i + lock_address.present? ? lock_address.lock_script.lock_info[:estimated_unlock_time].to_i : CkbUtils.time_in_milliseconds(Time.find_zone("UTC").parse("2020-12-31")) end end @@ -147,7 +147,7 @@ def third_released_timestamp_other @third_released_timestamp_other ||= begin lock_address = Address.find_by(address_hash: "ckb1q3w9q60tppt7l3j7r09qcp7lxnp3vcanvgha8pmvsa3jplykxn32sdufwedw7a0w9dkvhpsah4mdk2gkfq63e0q6qzzqxzq8yqnqq85p") - lock_address.present? ? lock_address.lock_script.lock_info[:estimated_unlock_time].to_i : Time.find_zone("UTC").parse("2022-12-31").to_i + lock_address.present? ? lock_address.lock_script.lock_info[:estimated_unlock_time].to_i : CkbUtils.time_in_milliseconds(Time.find_zone("UTC").parse("2022-12-31")) end end diff --git a/app/models/suggest_query.rb b/app/models/suggest_query.rb index b754a60b2..d53e613ef 100644 --- a/app/models/suggest_query.rb +++ b/app/models/suggest_query.rb @@ -47,10 +47,7 @@ def find_cached_address address = Address.cached_find(query_key) raise Api::V1::Exceptions::AddressNotFoundError if address.blank? - return AddressSerializer.new(address) if address.is_a?(NullAddress) - - presented_address = AddressPresenter.new(address) - AddressSerializer.new(presented_address) + AddressSerializer.new(address) end def find_udt_by_type_hash diff --git a/app/models/udt.rb b/app/models/udt.rb index 46dc2f85b..f9f1565fa 100644 --- a/app/models/udt.rb +++ b/app/models/udt.rb @@ -10,8 +10,38 @@ class Udt < ApplicationRecord attribute :code_hash, :ckb_hash def ckb_transactions - ckb_transaction_ids = CellOutput.udt.where(type_hash: type_hash).pluck("generated_by_id") + CellOutput.udt.where(type_hash: type_hash).pluck("consumed_by_id").compact - CkbTransaction.where(id: ckb_transaction_ids.uniq) + sql = + <<-SQL + SELECT + generated_by_id ckb_transaction_id + FROM + cell_outputs + WHERE + cell_type = #{CellOutput::cell_types['udt']} + AND + type_hash = '#{type_hash}' + + UNION + + SELECT + consumed_by_id ckb_transaction_id + FROM + cell_outputs + WHERE + cell_type = #{CellOutput::cell_types['udt']} + AND + type_hash = '#{type_hash}' + AND + consumed_by_id is not null + SQL + ckb_transaction_ids = CellOutput.select("ckb_transaction_id").from("(#{sql}) as cell_outputs") + CkbTransaction.where(id: ckb_transaction_ids.distinct) + end + + def h24_ckb_transactions_count + Rails.cache.realize("udt_h24_ckb_transactions_count_#{id}", expires_in: 1.hour) do + ckb_transactions.where("block_timestamp >= ?", CkbUtils.time_in_milliseconds(24.hours.ago)).count + end end end @@ -36,6 +66,7 @@ def ckb_transactions # published :boolean default(FALSE) # created_at :datetime not null # updated_at :datetime not null +# block_timestamp :decimal(30, ) # # Indexes # diff --git a/app/presenters/address_presenter.rb b/app/presenters/address_presenter.rb deleted file mode 100644 index 184e52cff..000000000 --- a/app/presenters/address_presenter.rb +++ /dev/null @@ -1,78 +0,0 @@ -class AddressPresenter - def initialize(object) - @object = object.is_a?(Array) ? object : [object] - end - - def id - object.first.id - end - - def address_hash - object.first.query_address - end - - def balance - object.reduce(0) { |sum, addr| sum + addr.balance.to_i } - end - - def dao_deposit - object.reduce(0) { |sum, addr| sum + addr.dao_deposit.to_i } - end - - def interest - object.reduce(0) { |sum, addr| sum + addr.interest.to_i } - end - - def live_cells_count - object.reduce(0) { |sum, addr| sum + addr.live_cells_count.to_i } - end - - def mined_blocks_count - object.reduce(0) { |sum, addr| sum + addr.mined_blocks_count.to_i } - end - - def lock_script - object.first.cached_lock_script - end - - def ckb_transactions_count - ckb_transactions.count - end - - def special? - object.first.special? - end - - def ckb_transactions - ckb_transaction_ids = AccountBook.where(address_id: object.pluck(:id)).select(:ckb_transaction_id).distinct - CkbTransaction.where(id: ckb_transaction_ids).recent - end - - def ckb_dao_transactions - address_ids = object.pluck(:id) - ckb_transaction_ids = CellOutput.where(address_id: address_ids).where(cell_type: %w(nervos_dao_deposit nervos_dao_withdrawing)).select("ckb_transaction_id") - CkbTransaction.where(id: ckb_transaction_ids) - end - - def ckb_udt_transactions(type_hash) - address_ids = object.pluck(:id) - ckb_transaction_ids = CellOutput.udt.where(address_id: address_ids, type_hash: type_hash).pluck("generated_by_id") + CellOutput.udt.where(address_id: address_ids, type_hash: type_hash).pluck("consumed_by_id").compact - CkbTransaction.where(id: ckb_transaction_ids.uniq) - end - - def lock_info - object.first.lock_script.lock_info - end - - def average_deposit_time - object.first.average_deposit_time - end - - def udt_accounts - object.first.udt_accounts - end - - private - - attr_reader :object -end diff --git a/app/serializers/distribution_data_serializer.rb b/app/serializers/distribution_data_serializer.rb index 136a5c0a1..5c81fc2ce 100644 --- a/app/serializers/distribution_data_serializer.rb +++ b/app/serializers/distribution_data_serializer.rb @@ -51,5 +51,11 @@ class DistributionDataSerializer attribute :miner_address_distribution, if: Proc.new { |_record, params| params && params[:indicator].include?("miner_address_distribution") - } + } do |object, params| + if rs = params[:indicator].match(/(\d+)/) + object.miner_address_distribution(rs[1].to_i) + else + object.miner_address_distribution + end + end end diff --git a/app/serializers/udt_serializer.rb b/app/serializers/udt_serializer.rb index 0d3b9a176..4acaa756c 100644 --- a/app/serializers/udt_serializer.rb +++ b/app/serializers/udt_serializer.rb @@ -1,7 +1,7 @@ class UdtSerializer include FastJsonapi::ObjectSerializer - attributes :symbol, :full_name, :icon_file + attributes :symbol, :full_name, :icon_file, :published, :description, :type_hash attribute :total_amount do |object| object.total_amount.to_s @@ -12,4 +12,10 @@ class UdtSerializer attribute :decimal do |object| object.decimal.to_s end + attribute :h24_ckb_transactions_count do |object| + object.h24_ckb_transactions_count.to_s + end + attributes :created_at do |object| + object.block_timestamp.to_s + end end diff --git a/config/routes.rb b/config/routes.rb index 050022217..b046b4a1b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -38,7 +38,7 @@ resources :block_statistics, only: :show resources :epoch_statistics, only: :show resources :market_data, only: :show - resources :udts, only: :show + resources :udts, only: %i(index show) resources :udt_transactions, only: :show resources :address_udt_transactions, only: :show resources :distribution_data, only: :show diff --git a/db/migrate/20200601121842_add_block_timestamp_to_udts.rb b/db/migrate/20200601121842_add_block_timestamp_to_udts.rb new file mode 100644 index 000000000..a9d0eaf88 --- /dev/null +++ b/db/migrate/20200601121842_add_block_timestamp_to_udts.rb @@ -0,0 +1,5 @@ +class AddBlockTimestampToUdts < ActiveRecord::Migration[6.0] + def change + add_column :udts, :block_timestamp, :decimal, precision: 30 + end +end diff --git a/db/schema.rb b/db/schema.rb index 52ae6c958..a6083dd0a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_05_25_100826) do +ActiveRecord::Schema.define(version: 2020_06_01_121842) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -388,6 +388,7 @@ t.boolean "published", default: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false + t.decimal "block_timestamp", precision: 30 t.index ["type_hash"], name: "index_udts_on_type_hash", unique: true end diff --git a/doc/api.raml b/doc/api.raml index 0cdfef5b0..2a6130096 100644 --- a/doc/api.raml +++ b/doc/api.raml @@ -779,6 +779,15 @@ types: }, "icon_file": { type: "string" + }, + "description": { + type: "string" + }, + "created_at": { + type: "string" + }, + "published": { + type: "boolean" } } } @@ -1014,6 +1023,15 @@ types: } } + udts_response: { + type: object, + properties: { + "data": { + "type": "udt[]", + } + } + } + index_statistic_response: { type: object, properties: { @@ -3690,6 +3708,66 @@ types: } /udts: + get: + description: Returns udts in reverse chronological order by addresses count. + responses: + 200: + body: + application/vnd.api+json: + type: udts_response + example: | + { + "data": [ + { + "id": "1", + "type": "udt", + "attributes": { + "symbol": "kfc", + "full_name": "Kingdom Fly Coin", + "icon_file": "data:image/png;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAQDAwQDAwQEAwQFBAQFBgoHBgYGBg0JCggKDw0QEA8NDw4RExgUERIXEg4PFRwVFxkZGxsbEBQdHx0aHxgaGxr/2wBDAQQFBQYFBgwHBwwaEQ8RGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhr/wAARCAAoACgDASIAAhEBAxEB/8QAGwAAAgIDAQAAAAAAAAAAAAAAAAYEBwEFCAP/xAAtEAABAgUCBAUEAwAAAAAAAAABAgQAAwUREgYTFCExUSJBYXHwBxUygRaRwf/EABoBAAIDAQEAAAAAAAAAAAAAAAACAwUGBAf/xAAiEQABAwQCAgMAAAAAAAAAAAABAAIRAwQhMUFRBhMiQoH/2gAMAwEAAhEDEQA/AO83TtDWVnM6eXeFhzWJ7hRCV4pvyANvn7vGKu6LlyoXOKPCB8+c4pmhUKo6Zq8qq1yTw1PkZ7kwzQvHIEDkCT1IhXOhVd5ePtH0wKZc1xyeGjGTjWZzGlbW4c872Ve94nNa1ObqSCvNPmFG/wA/UUt9QdQU+tCn/anO+ZRmblkqTa+NuoHYxpadpOt1NtJdsmxmt5hulW8kXsbHkT6GENTMAKmr+QOFy6hbUfbHLTPXQOphdWNHct5KEyUfcdoIVqM6LV0hJJwX4VD5/f6giVa1QJmQUTMvl53ipdQfUEVqlOaf9vMgzbDc3srWUD0t6RdFYaqbuZhIOK7qSf8APnaOfdJ06RU9Rtmz+SZreYZmSTcA2SSOY9oiqE4A5WS8gr3LXUbag6PbLT+wOjG+F76T0mNTh2S7LXhyjpLzyyv6jtDKNUjRJTQOEL7hbDf3NvLLxfjY2tlbr5QaqvokNP4ungi7Kt8AbmWNrfle1sj07xsqDQafqalN6rXG3Ev54O7NKlIviogcgQByAhACMDaqrS0fbPNpaENuGj5O20tOYEznLfqNHPbvLyuDLvl5WgifR2hcOkGxCEG6j7QR0L0JNDtpLeSjLmj2PaFZ3R3DVRKZe4i/JSReCCBCgbaivAgFV7RsGdHcuFC6DLRfmoi0EECE0NGktnKEuUPc94IIIEL/2Q==", + "total_amount": "10000000000", + "addresses_count": "3", + "decimal": "6", + "h24_ckb_transactions_count": "0", + "published": true, + "description": "Kingdom Fly Coin", + "created_at": "1591096409" + } + }, + { + "id": "4", + "type": "udt", + "attributes": { + "symbol": null, + "full_name": null, + "icon_file": null, + "total_amount": "100000000000000000000", + "addresses_count": "3", + "decimal": "", + "h24_ckb_transactions_count": "0", + "published": false, + "description": "", + "created_at": "1591096409" + } + }, + { + "id": "14", + "type": "udt", + "attributes": { + "symbol": null, + "full_name": null, + "icon_file": null, + "total_amount": "9999900000", + "addresses_count": "1", + "decimal": "", + "h24_ckb_transactions_count": "0", + "published": false, + "description": "", + "created_at": "1591096409" + } + }] + } + /{type_hash}: uriParameters: type_hash: diff --git a/lib/tasks/migration/fill_block_timestamp_to_udt.rake b/lib/tasks/migration/fill_block_timestamp_to_udt.rake new file mode 100644 index 000000000..e2f21586c --- /dev/null +++ b/lib/tasks/migration/fill_block_timestamp_to_udt.rake @@ -0,0 +1,20 @@ +namespace :migration do + task fill_block_timestamp_to_udt: :environment do + udts = Udt.all + progress_bar = ProgressBar.create({ + total: udts.count, + format: "%e %B %p%% %c/%C" + }) + + values = + udts.map do |udt| + progress_bar.increment + cell_output = CellOutput.find_by(type_hash: udt.type_hash) + { id: udt.id, block_timestamp: cell_output.block_timestamp, created_at: udt.created_at, updated_at: Time.current } + end + + Udt.upsert_all(values) + + puts "done" + end +end diff --git a/public/api_doc.html b/public/api_doc.html index 67b351a84..62071c180 100644 --- a/public/api_doc.html +++ b/public/api_doc.html @@ -2150,7 +2150,58 @@

/market_data

get

Returns market data by given indicator

/udts

get

Returns a UDT by type hash

/udts

get

Returns udts in reverse chronological order by addresses count.

get

Returns a UDT by type hash