Skip to content

Commit

Permalink
Merge pull request #1454 from nervosnetwork/testnet
Browse files Browse the repository at this point in the history
Deploy to mainnet
  • Loading branch information
rabbitz authored Oct 10, 2023
2 parents 4613755 + 3af1dbd commit 2510bf5
Show file tree
Hide file tree
Showing 34 changed files with 665 additions and 156 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ jobs:
image-name: '${{ steps.docker_build.outputs.imageFullName }}'
image-tag: '${{ steps.docker_build.outputs.tags }}'
steps:
- name: Update Package List and Remove Dotnet
run: |
sudo apt-get update
sudo apt-get remove -y '^dotnet-.*'
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
Expand Down
31 changes: 31 additions & 0 deletions app/controllers/api/v1/udt_verifications_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module Api
module V1
class UdtVerificationsController < ApplicationController
before_action :check_udt_info, only: :update
before_action :set_locale, only: :update

def update
udt_verification = UdtVerification.find_or_create_by(udt_id: @udt.id)

udt_verification.refresh_token!(request.remote_ip)
UdtVerificationMailer.with(email: @udt.email, token: udt_verification.token,
locale: @locale).send_token.deliver_later
render json: :ok
rescue UdtVerification::TokenSentTooFrequentlyError
raise Api::V1::Exceptions::TokenSentTooFrequentlyError
end

private

def check_udt_info
@udt = Udt.find_by(type_hash: params[:id])
raise Api::V1::Exceptions::UdtNotFoundError if @udt.nil?
raise Api::V1::Exceptions::UdtNoContactEmailError if @udt.email.blank?
end

def set_locale
@locale = params[:locale] == "zh_CN" ? "zh_CN" : "en"
end
end
end
end
17 changes: 15 additions & 2 deletions app/controllers/api/v1/udts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,27 @@ def update
icon_file: params[:icon_file],
uan: params[:uan],
display_name: params[:display_name],
contact_info: params[:contact_info]
email: params[:email]
}
udt.update!(attrs)
if udt.email.blank?
raise Api::V1::Exceptions::UdtInfoInvalidError.new("Email can't be blank") if params[:email].blank?

udt.update!(attrs)
else
raise Api::V1::Exceptions::UdtVerificationNotFoundError if udt.udt_verification.nil?

udt.udt_verification.validate_token!(params[:token])
udt.update!(attrs)
end
render json: :ok
rescue ActiveRecord::RecordNotFound
raise Api::V1::Exceptions::UdtNotFoundError
rescue ActiveRecord::RecordInvalid => e
raise Api::V1::Exceptions::UdtInfoInvalidError.new(e)
rescue UdtVerification::TokenExpiredError
raise Api::V1::Exceptions::TokenExpiredError
rescue UdtVerification::TokenNotMatchError
raise Api::V1::Exceptions::TokenNotMatchError
end

def show
Expand Down
39 changes: 18 additions & 21 deletions app/controllers/api/v2/scripts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,55 +9,52 @@ class ScriptsController < BaseController
def general_info
head :not_found and return if @script.blank? || @contract.blank?

key = ["contract_info", @contract.code_hash, @contract.hash_type]
result =
Rails.cache.fetch(key, expires_in: 10.minutes) do
get_script_content
end
render json: { data: result }
expires_in 15.seconds, public: true, must_revalidate: true, stale_while_revalidate: 5.seconds
render json: { data: get_script_content }
end

def ckb_transactions
head :not_found and return if @contract.blank?

expires_in 15.seconds, public: true, must_revalidate: true, stale_while_revalidate: 5.seconds
scope = CellDependency.where(contract_id: @contract.id).order(ckb_transaction_id: :desc)
tx_ids = scope.page(@page).per(@page_size).pluck(:ckb_transaction_id)
@ckb_transactions = CkbTransaction.find(tx_ids)
@total = scope.count
@ckb_transactions = @contract.ckb_transactions.order(id: :desc).page(@page).per(@page_size)
end

def deployed_cells
head :not_found and return if @contract.blank?

expires_in 15.seconds, public: true, must_revalidate: true, stale_while_revalidate: 5.seconds
@deployed_cells = @contract.deployed_cells.page(@page).per(@page_size).fast_page
@deployed_cells = @contract.deployed_cell_outputs.live.page(@page).per(@page_size)
end

def referring_cells
head :not_found and return if @contract.blank?

expires_in 15.seconds, public: true, must_revalidate: true, stale_while_revalidate: 5.seconds
@referring_cells = @contract.referring_cells.page(@page).per(@page_size).fast_page
@referring_cells = @contract.referring_cell_outputs.live.page(@page).per(@page_size)
end

private

def get_script_content
referring_cells = @contract&.referring_cell_outputs
deployed_cells = @contract&.deployed_cell_outputs&.live
transactions = @contract&.cell_dependencies
deployed_cells = @contract.deployed_cell_outputs
if deployed_cells.present?
deployed_type_script = deployed_cells[0].type_script
if deployed_type_script.code_hash == Settings.type_id_code_hash
type_id = deployed_type_script.script_hash
end
end

{
id: @script.id,
id: type_id,
code_hash: @script.code_hash,
hash_type: @script.hash_type,
script_type: @script.class.to_s,
capacity_of_deployed_cells: deployed_cells&.sum(:capacity),
capacity_of_referring_cells: referring_cells&.sum(:capacity),
count_of_transactions: transactions&.count.to_i,
count_of_deployed_cells: deployed_cells&.count.to_i,
count_of_referring_cells: referring_cells&.count.to_i
capacity_of_deployed_cells: @contract.total_deployed_cells_capacity,
capacity_of_referring_cells: @contract.total_referring_cells_capacity,
count_of_transactions: @contract.ckb_transactions_count,
count_of_deployed_cells: @contract.deployed_cells_count,
count_of_referring_cells: @contract.referring_cells_count
}
end

Expand Down
37 changes: 37 additions & 0 deletions app/lib/api/v1/exceptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,13 @@ def initialize
super code: 1027, status: 404, title: "URI parameters invalid", detail: "code hash should be start with 0x", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class ScriptHashTypeParamsInvalidError < Error
def initialize
super code: 1028, status: 404, title: "URI parameters invalid", detail: "hash type should be 'type'", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class ScriptNotFoundError < Error
def initialize
super code: 1029, status: 404, title: "Script not found", detail: "Script not found", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
Expand All @@ -191,6 +193,41 @@ def initialize(detail)
end
end

class UdtVerificationInvalidError < Error
def initialize(detail)
super code: 1031, status: 400, title: "UDT verification invalid", detail: detail, href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class UdtVerificationNotFoundError < Error
def initialize
super code: 1032, status: 404, title: "UDT Verification Not Found", detail: "No UDT verification records found by given type hash", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class UdtNoContactEmailError < Error
def initialize
super code: 1033, status: 400, title: "UDT has no contact email", detail: "", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class TokenExpiredError < Error
def initialize
super code: 1034, status: 400, title: "Token has expired", detail: "", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class TokenNotMatchError < Error
def initialize
super code: 1035, status: 400, title: "Token is not matched", detail: "", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class TokenSentTooFrequentlyError < Error
def initialize
super code: 1036, status: 400, title: "Token sent too frequently", detail: "", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end
end
end
end
12 changes: 12 additions & 0 deletions app/mailers/udt_verification_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class UdtVerificationMailer < ApplicationMailer
default from: "[email protected]"

def send_token
email = params[:email]
@token = params[:token]
locale = params[:locale] || "en"
I18n.with_locale(locale) do
mail(to: email, subject: "Token Info Verification")
end
end
end
29 changes: 17 additions & 12 deletions app/models/contract.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,23 @@ def self.create_initial_data
#
# Table name: contracts
#
# id :bigint not null, primary key
# code_hash :binary
# hash_type :string
# deployed_args :string
# role :string default("type_script")
# name :string
# symbol :string
# description :string
# verified :boolean default(FALSE)
# created_at :datetime not null
# updated_at :datetime not null
# deprecated :boolean
# id :bigint not null, primary key
# code_hash :binary
# hash_type :string
# deployed_args :string
# role :string default("type_script")
# name :string
# symbol :string
# description :string
# verified :boolean default(FALSE)
# created_at :datetime not null
# updated_at :datetime not null
# deprecated :boolean
# ckb_transactions_count :decimal(30, ) default(0)
# deployed_cells_count :decimal(30, ) default(0)
# referring_cells_count :decimal(30, ) default(0)
# total_deployed_cells_capacity :decimal(30, ) default(0)
# total_referring_cells_capacity :decimal(30, ) default(0)
#
# Indexes
#
Expand Down
8 changes: 6 additions & 2 deletions app/models/udt.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
class Udt < ApplicationRecord
MAX_PAGINATES_PER = 100

belongs_to :nrc_factory_cell, optional: true

MAX_PAGINATES_PER = 100
has_one :udt_verification

enum udt_type: { sudt: 0, m_nft_token: 1, nrc_721_token: 2, spore_cell: 3 }

validates_presence_of :total_amount
validates_length_of :symbol, minimum: 1, maximum: 16, allow_nil: true
validates_length_of :full_name, minimum: 1, maximum: 100, allow_nil: true
validates :decimal, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 39 }, allow_nil: true
validates :total_amount, numericality: { greater_than_or_equal_to: 0 }
validates :email, format: { with: /\A(.+)@(.+)\z/, message: "Not a valid email" }, allow_nil: true

attribute :code_hash, :ckb_hash

Expand Down Expand Up @@ -60,7 +64,7 @@ def type_script
# display_name :string
# uan :string
# h24_ckb_transactions_count :bigint default(0)
# contact_info :string
# email :string
#
# Indexes
#
Expand Down
43 changes: 43 additions & 0 deletions app/models/udt_verification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
class UdtVerification < ApplicationRecord
SENT_FREQUENCY_MINUTES = 1
KEEP_ALIVE_MINUTES = 10

class TokenExpiredError < StandardError; end
class TokenNotMatchError < StandardError; end
class TokenSentTooFrequentlyError < StandardError; end

belongs_to :udt

def refresh_token!(ip)
raise TokenSentTooFrequentlyError if sent_at.present? && self.sent_at + SENT_FREQUENCY_MINUTES.minutes > Time.now

self.token = rand(999999).to_s.rjust(6, "0")
self.sent_at = Time.now
self.last_ip = ip
self.save!
end

def validate_token!(token_params)
raise TokenExpiredError if self.sent_at + KEEP_ALIVE_MINUTES.minutes < Time.now
raise TokenNotMatchError if token != token_params.to_i
end
end

# == Schema Information
#
# Table name: udt_verifications
#
# id :bigint not null, primary key
# token :integer
# sent_at :datetime
# last_ip :inet
# udt_id :bigint
# udt_type_hash :integer
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_udt_verifications_on_udt_id (udt_id)
# index_udt_verifications_on_udt_type_hash (udt_type_hash) UNIQUE
#
1 change: 1 addition & 0 deletions app/utils/ckb_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ def self.parse_spore_cluster_data(hex_data)
description_offset = [data.slice(16, 8)].pack("H*").unpack1("l") * 2
name = [data.slice(name_offset + 8..description_offset - 1)].pack("H*")
description = [data.slice(description_offset + 8..-1)].pack("H*")
name = "#{name[0,97]}..." if name.length > 100
{ name: name, description: description }
rescue => _e
{ name: nil, description: nil }
Expand Down
2 changes: 1 addition & 1 deletion app/views/api/v2/scripts/ckb_transactions.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ json.data do
json.display_outputs tx.display_outputs
end
json.meta do
json.total @total
json.total @contract.ckb_transactions_count
json.page_size @page_size.to_i
end
end
45 changes: 22 additions & 23 deletions app/views/api/v2/scripts/deployed_cells.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
json.data do
json.deployed_cells @deployed_cells do |deployed_cell|
cell_output = deployed_cell.cell_output
json.id deployed_cell.cell_output.id
json.capacity deployed_cell.cell_output.capacity
json.ckb_transaction_id deployed_cell.cell_output.ckb_transaction_id
json.created_at deployed_cell.cell_output.created_at
json.updated_at deployed_cell.cell_output.updated_at
json.status cell_output.status
json.address_id cell_output.address_id
json.block_id cell_output.block_id
json.tx_hash cell_output.tx_hash
json.cell_index cell_output.cell_index
json.consumed_by_id cell_output.consumed_by_id
json.cell_type cell_output.cell_type
json.data_size cell_output.data_size
json.occupied_capacity cell_output.occupied_capacity
json.block_timestamp cell_output.block_timestamp
json.consumed_block_timestamp cell_output.consumed_block_timestamp
json.type_hash cell_output.type_hash
json.udt_amount cell_output.udt_amount
json.dao cell_output.dao
json.lock_script_id cell_output.lock_script_id
json.type_script_id cell_output.type_script_id
json.id deployed_cell.id
json.capacity deployed_cell.capacity
json.ckb_transaction_id deployed_cell.ckb_transaction_id
json.created_at deployed_cell.created_at
json.updated_at deployed_cell.updated_at
json.status deployed_cell.status
json.address_id deployed_cell.address_id
json.block_id deployed_cell.block_id
json.tx_hash deployed_cell.tx_hash
json.cell_index deployed_cell.cell_index
json.consumed_by_id deployed_cell.consumed_by_id
json.cell_type deployed_cell.cell_type
json.data_size deployed_cell.data_size
json.occupied_capacity deployed_cell.occupied_capacity
json.block_timestamp deployed_cell.block_timestamp
json.consumed_block_timestamp deployed_cell.consumed_block_timestamp
json.type_hash deployed_cell.type_hash
json.udt_amount deployed_cell.udt_amount
json.dao deployed_cell.dao
json.lock_script_id deployed_cell.lock_script_id
json.type_script_id deployed_cell.type_script_id
end
json.meta do
json.total @deployed_cells.total_count
json.total @contract.deployed_cells_count
json.page_size @page_size.to_i
end
end
Loading

0 comments on commit 2510bf5

Please sign in to comment.