Skip to content

Commit

Permalink
Merge pull request #566 from nervosnetwork/rc/v0.9.4
Browse files Browse the repository at this point in the history
[ᚬmaster] Rc/v0.9.4
  • Loading branch information
shaojunda authored Feb 13, 2020
2 parents 528db01 + 3e2e490 commit b95b223
Show file tree
Hide file tree
Showing 28 changed files with 813 additions and 797 deletions.
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Style/TrailingCommaInHashLiteral:
Metrics/LineLength:
Enabled: false

Layout/IndentFirstHashElement:
Layout/FirstHashElementIndentation:
EnforcedStyle: consistent

Style/BracesAroundHashParameters:
Expand Down
10 changes: 5 additions & 5 deletions .rubocop_thoughtbot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ Style/PerlBackrefs:
Naming/PredicateName:
Description: 'Check the names of predicate methods.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark'
NamePrefixBlacklist:
ForbiddenPrefixes:
- is_
Exclude:
- spec/**/*
Expand Down Expand Up @@ -403,7 +403,7 @@ Style/WordArray:

# Layout

Layout/AlignParameters:
Layout/ParameterAlignment:
Description: 'Here we check if the parameters on a multi-line method call or definition are aligned.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-double-indent'
Enabled: false
Expand Down Expand Up @@ -471,7 +471,7 @@ Lint/DeprecatedClassMethods:
Description: 'Check for deprecated class method calls.'
Enabled: false

Lint/DuplicatedKey:
Lint/DuplicateHashKey:
Description: 'Check for duplicate keys in hash literals.'
Enabled: false

Expand All @@ -487,7 +487,7 @@ Lint/FormatParameterMismatch:
Description: 'The number of parameters to format/sprint must match the fields.'
Enabled: false

Lint/HandleExceptions:
Lint/SuppressedException:
Description: "Don't suppress exception."
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions'
Enabled: false
Expand Down Expand Up @@ -533,7 +533,7 @@ Lint/UnderscorePrefixedVariableName:
Description: 'Do not use prefix `_` for a variable that is used.'
Enabled: false

Lint/UnneededCopDisableDirective:
Lint/RedundantCopDisableDirective:
Description: >-
Checks for rubocop:disable comments that can be removed.
Note: this cop is not disabled when disabling all cops.
Expand Down
1,359 changes: 647 additions & 712 deletions CHANGELOG.md

Large diffs are not rendered by default.

26 changes: 20 additions & 6 deletions app/controllers/api/v1/address_transactions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ class AddressTransactionsController < ApplicationController
before_action :validate_pagination_params, :pagination_params

def show
address = Address.find_address!(params[:id])
raise Api::V1::Exceptions::AddressNotFoundError if address.is_a?(NullAddress)
@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)
options = FastJsonapi::PaginationMetaGenerator.new(request: request, records: ckb_transactions, page: @page, page_size: @page_size).call
presented_address = AddressPresenter.new(@address)
@ckb_transactions = presented_address.ckb_transactions.recent.distinct.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, address: address } }))
render json: json_result
end

private
Expand All @@ -32,6 +32,20 @@ def pagination_params
@page = params[:page] || 1
@page_size = params[:page_size] || CkbTransaction.default_per_page
end

def json_result
ckb_transaction_serializer = CkbTransactionSerializer.new(@ckb_transactions, @options.merge({ params: { previews: true, address: @address } }))

if QueryKeyUtils.valid_address?(params[:id])
if @address.address_hash == @address.query_address
ckb_transaction_serializer
else
ckb_transaction_serializer.serialized_json.gsub(@address.address_hash, @address.query_address)
end
else
ckb_transaction_serializer
end
end
end
end
end
11 changes: 10 additions & 1 deletion app/models/address.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class Address < ApplicationRecord

after_commit :flush_cache

attr_accessor :query_address

def lock_script
LockScript.where(address: self).first
end
Expand All @@ -36,7 +38,14 @@ def self.cached_find(query_key)
if QueryKeyUtils.valid_hex?(query_key)
find_by(lock_hash: query_key)
else
where(address_hash: query_key).to_a.presence || NullAddress.new(query_key)
lock_hash = CkbUtils.parse_address(query_key).script.compute_hash
address = find_by(lock_hash: lock_hash)
if address.present?
address.query_address = query_key
address
else
NullAddress.new(query_key)
end
end
end
end
Expand Down
21 changes: 11 additions & 10 deletions app/models/cell_output.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ class CellOutput < ApplicationRecord

attribute :tx_hash, :ckb_hash

scope :consumed_after, -> (block_timestamp) { where("consumed_block_timestamp >= ?", block_timestamp) }
scope :consumed_before, -> (block_timestamp) { where("consumed_block_timestamp <= ?", block_timestamp) }
scope :unconsumed_at, -> (block_timestamp) { where("consumed_block_timestamp > ? or consumed_block_timestamp is null", block_timestamp) }
scope :generated_after, -> (block_timestamp) { where("block_timestamp >= ?", block_timestamp) }
scope :generated_before, -> (block_timestamp) { where("block_timestamp <= ?", block_timestamp) }
scope :consumed_after, ->(block_timestamp) { where("consumed_block_timestamp >= ?", block_timestamp) }
scope :consumed_before, ->(block_timestamp) { where("consumed_block_timestamp <= ?", block_timestamp) }
scope :unconsumed_at, ->(block_timestamp) { where("consumed_block_timestamp > ? or consumed_block_timestamp is null", block_timestamp) }
scope :generated_after, ->(block_timestamp) { where("block_timestamp >= ?", block_timestamp) }
scope :generated_before, ->(block_timestamp) { where("block_timestamp <= ?", block_timestamp) }

after_commit :flush_cache

Expand All @@ -35,11 +35,12 @@ def node_output
end

def cache_keys
%W(previous_cell_output/#{tx_hash}/#{cell_index} normal_tx_display_inputs_previews_true_#{ckb_transaction_id}
normal_tx_display_inputs_previews_false_#{ckb_transaction_id} normal_tx_display_inputs_previews_true_#{consumed_by_id}
normal_tx_display_inputs_previews_false_#{consumed_by_id} normal_tx_display_outputs_previews_true_#{ckb_transaction_id}
normal_tx_display_outputs_previews_false_#{ckb_transaction_id} normal_tx_display_outputs_previews_true_#{consumed_by_id}
normal_tx_display_outputs_previews_false_#{consumed_by_id}
%W(
previous_cell_output/#{tx_hash}/#{cell_index} normal_tx_display_inputs_previews_true_#{ckb_transaction_id}
normal_tx_display_inputs_previews_false_#{ckb_transaction_id} normal_tx_display_inputs_previews_true_#{consumed_by_id}
normal_tx_display_inputs_previews_false_#{consumed_by_id} normal_tx_display_outputs_previews_true_#{ckb_transaction_id}
normal_tx_display_outputs_previews_false_#{ckb_transaction_id} normal_tx_display_outputs_previews_true_#{consumed_by_id}
normal_tx_display_outputs_previews_false_#{consumed_by_id}
)
end

Expand Down
7 changes: 4 additions & 3 deletions app/models/ckb_transaction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class CkbTransaction < ApplicationRecord
scope :recent, -> { order(block_timestamp: :desc) }
scope :cellbase, -> { where(is_cellbase: true) }
scope :normal, -> { where(is_cellbase: false) }
scope :created_after, -> (block_timestamp) { where("block_timestamp >= ?", block_timestamp) }
scope :created_before, -> (block_timestamp) { where("block_timestamp <= ?", block_timestamp) }
scope :created_after, ->(block_timestamp) { where("block_timestamp >= ?", block_timestamp) }
scope :created_before, ->(block_timestamp) { where("block_timestamp <= ?", block_timestamp) }

after_commit :flush_cache
before_destroy :recover_dead_cell
Expand Down Expand Up @@ -104,7 +104,8 @@ def attributes_for_dao_input(nervos_dao_withdrawing_cell, is_phase2 = true)
attributes = { compensation_started_block_number: compensation_started_block.number, compensation_ended_block_number: compensation_ended_block.number, compensation_started_timestamp: compensation_started_block.timestamp, compensation_ended_timestamp: compensation_ended_block.timestamp, interest: interest }
if is_phase2
locked_until_block = Block.select(:number, :timestamp).find(block_id)
attributes.merge!({ locked_until_block_number: locked_until_block.number, locked_until_block_timestamp: locked_until_block.timestamp })
attributes[:locked_until_block_number] = locked_until_block.number
attributes[:locked_until_block_timestamp] = locked_until_block.timestamp
end

CkbUtils.hash_value_to_s(attributes)
Expand Down
19 changes: 10 additions & 9 deletions app/models/dao_contract.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ def estimated_apc(deposit_epoch = tip_block_fraction_epoch, deposited_epochs = E
checkpoints.unshift(start_epoch_number.to_i) if checkpoints.empty? || checkpoints[0] > start_epoch_number
checkpoints.push(scaled_end_epoch_number.to_i) if checkpoints.last < scaled_end_epoch_number
end_epoch_numbers = checkpoints[1..-1]
rates = end_epoch_numbers.each_with_index.map do |inner_end_epoch_number, index|
epoch_index = deposit_epoch.index * 1800 / deposit_epoch.length
start_epoch = OpenStruct.new(number: checkpoints[index], index: epoch_index, length: 1800)
end_epoch = OpenStruct.new(number: inner_end_epoch_number, index: epoch_index, length: 1800)
rate(start_epoch, end_epoch)
end
rates =
end_epoch_numbers.each_with_index.map do |inner_end_epoch_number, index|
epoch_index = deposit_epoch.index * 1800 / deposit_epoch.length
start_epoch = OpenStruct.new(number: checkpoints[index], index: epoch_index, length: 1800)
end_epoch = OpenStruct.new(number: inner_end_epoch_number, index: epoch_index, length: 1800)
rate(start_epoch, end_epoch)
end
rate = rates.reduce(1) { |memo, rate| memo * (1 + rate) } - 1
(rate * 100) / ratio
end
Expand Down Expand Up @@ -89,7 +90,7 @@ def latest_daily_statistic

def alpha(start_epoch_number)
i = ((start_epoch_number + 1) / EPOCHS_IN_PERIOD).floor
p = PRIMARY_ISSUANCE_PER_YEAR_BASE / 2 ** i / 2190
p = PRIMARY_ISSUANCE_PER_YEAR_BASE / 2**i / 2190
p / SECONDARY_ISSUANCE_PER_EPOCH
end

Expand All @@ -105,8 +106,8 @@ def total_issuance(start_epoch)

def primary_issuance(start_epoch)
epochs = (start_epoch.number / EPOCHS_IN_PERIOD).floor
epochs.times.reduce(GENESIS_ISSUANCE) { |memo, item| memo + (ANNUAL_PRIMARY_ISSUANCE_BASE * YEARS_IN_PERIOD) / 2 ** item } \
+ (ANNUAL_PRIMARY_ISSUANCE_BASE * ((start_epoch.number + 1 - epochs * EPOCHS_IN_PERIOD) / EPOCHS_IN_ONE_NATURAL_YEAR)) / 2 ** epochs
epochs.times.reduce(GENESIS_ISSUANCE) { |memo, item| memo + (ANNUAL_PRIMARY_ISSUANCE_BASE * YEARS_IN_PERIOD) / 2**item } \
+ (ANNUAL_PRIMARY_ISSUANCE_BASE * ((start_epoch.number + 1 - epochs * EPOCHS_IN_PERIOD) / EPOCHS_IN_ONE_NATURAL_YEAR)) / 2**epochs
end

def secondary_issuance(start_epoch)
Expand Down
2 changes: 1 addition & 1 deletion app/presenters/address_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def id
end

def address_hash
object.first.address_hash
object.first.query_address
end

def balance
Expand Down
1 change: 1 addition & 0 deletions app/services/charts/block_statistic_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def call
end

private

attr_reader :block_number
end
end
24 changes: 13 additions & 11 deletions app/services/charts/daily_statistic_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def claimed_compensation
end
else
claimed_compensation_today =
CellOutput.nervos_dao_withdrawing.consumed_after(started_at).consumed_before(ended_at).reduce(0) do |memo, nervos_dao_withdrawing_cell|
CellOutput.nervos_dao_withdrawing.consumed_after(started_at).consumed_before(ended_at).reduce(0) do |memo, nervos_dao_withdrawing_cell|
memo + CkbUtils.dao_interest(nervos_dao_withdrawing_cell)
end

Expand Down Expand Up @@ -198,17 +198,19 @@ def unmade_dao_interests
def average_deposit_time
interest_bearing_deposits = 0
uninterest_bearing_deposits = 0
sum_interest_bearing = CellOutput.nervos_dao_withdrawing.generated_before(ended_at).unconsumed_at(ended_at).reduce(0) do |memo, nervos_dao_withdrawing_cell|
nervos_dao_withdrawing_cell_generated_tx = nervos_dao_withdrawing_cell.generated_by
nervos_dao_deposit_cell = nervos_dao_withdrawing_cell_generated_tx.cell_inputs.order(:id)[nervos_dao_withdrawing_cell.cell_index].previous_cell_output
interest_bearing_deposits += nervos_dao_deposit_cell.capacity
memo + nervos_dao_deposit_cell.capacity * (nervos_dao_withdrawing_cell.block_timestamp - nervos_dao_deposit_cell.block_timestamp) / MILLISECONDS_IN_DAY
end
sum_uninterest_bearing = CellOutput.nervos_dao_deposit.generated_before(ended_at).unconsumed_at(ended_at).reduce(0) do |memo, nervos_dao_deposit_cell|
uninterest_bearing_deposits += nervos_dao_deposit_cell.capacity
sum_interest_bearing =
CellOutput.nervos_dao_withdrawing.generated_before(ended_at).unconsumed_at(ended_at).reduce(0) do |memo, nervos_dao_withdrawing_cell|
nervos_dao_withdrawing_cell_generated_tx = nervos_dao_withdrawing_cell.generated_by
nervos_dao_deposit_cell = nervos_dao_withdrawing_cell_generated_tx.cell_inputs.order(:id)[nervos_dao_withdrawing_cell.cell_index].previous_cell_output
interest_bearing_deposits += nervos_dao_deposit_cell.capacity
memo + nervos_dao_deposit_cell.capacity * (nervos_dao_withdrawing_cell.block_timestamp - nervos_dao_deposit_cell.block_timestamp) / MILLISECONDS_IN_DAY
end
sum_uninterest_bearing =
CellOutput.nervos_dao_deposit.generated_before(ended_at).unconsumed_at(ended_at).reduce(0) do |memo, nervos_dao_deposit_cell|
uninterest_bearing_deposits += nervos_dao_deposit_cell.capacity

memo + nervos_dao_deposit_cell.capacity * (ended_at - nervos_dao_deposit_cell.block_timestamp) / MILLISECONDS_IN_DAY
end
memo + nervos_dao_deposit_cell.capacity * (ended_at - nervos_dao_deposit_cell.block_timestamp) / MILLISECONDS_IN_DAY
end

(sum_interest_bearing + sum_uninterest_bearing) / (interest_bearing_deposits + uninterest_bearing_deposits)
end
Expand Down
1 change: 1 addition & 0 deletions app/services/charts/epoch_statistic_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def call
end

private

attr_reader :target_epoch_number
end
end
2 changes: 1 addition & 1 deletion app/utils/ckb_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def self.update_current_block_mining_info(block)
return if block.blank?

miner_address = block.miner_address
MiningInfo.create!(block: block, block_number:block.number, address: miner_address, status: "mined")
MiningInfo.create!(block: block, block_number: block.number, address: miner_address, status: "mined")
miner_address.increment!(:mined_blocks_count)
end

Expand Down
24 changes: 13 additions & 11 deletions app/workers/address_average_deposit_time_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,20 @@ def cal_average_deposit_time(address)
interest_bearing_deposits = 0
uninterest_bearing_deposits = 0
milliseconds_in_day = BigDecimal(24 * 60 * 60 * 1000)
ended_at = time_in_milliseconds(Time.current)
sum_interest_bearing = address.cell_outputs.nervos_dao_withdrawing.unconsumed_at(ended_at).reduce(0) do |memo, nervos_dao_withdrawing_cell|
nervos_dao_withdrawing_cell_generated_tx = nervos_dao_withdrawing_cell.generated_by
nervos_dao_deposit_cell = nervos_dao_withdrawing_cell_generated_tx.cell_inputs.order(:id)[nervos_dao_withdrawing_cell.cell_index].previous_cell_output
interest_bearing_deposits += nervos_dao_deposit_cell.capacity
memo + nervos_dao_deposit_cell.capacity * (nervos_dao_withdrawing_cell.block_timestamp - nervos_dao_deposit_cell.block_timestamp) / milliseconds_in_day
end
sum_uninterest_bearing = address.cell_outputs.nervos_dao_deposit.unconsumed_at(ended_at).reduce(0) do |memo, nervos_dao_deposit_cell|
uninterest_bearing_deposits += nervos_dao_deposit_cell.capacity
ended_at = time_in_milliseconds(Time.current)
sum_interest_bearing =
address.cell_outputs.nervos_dao_withdrawing.unconsumed_at(ended_at).reduce(0) do |memo, nervos_dao_withdrawing_cell|
nervos_dao_withdrawing_cell_generated_tx = nervos_dao_withdrawing_cell.generated_by
nervos_dao_deposit_cell = nervos_dao_withdrawing_cell_generated_tx.cell_inputs.order(:id)[nervos_dao_withdrawing_cell.cell_index].previous_cell_output
interest_bearing_deposits += nervos_dao_deposit_cell.capacity
memo + nervos_dao_deposit_cell.capacity * (nervos_dao_withdrawing_cell.block_timestamp - nervos_dao_deposit_cell.block_timestamp) / milliseconds_in_day
end
sum_uninterest_bearing =
address.cell_outputs.nervos_dao_deposit.unconsumed_at(ended_at).reduce(0) do |memo, nervos_dao_deposit_cell|
uninterest_bearing_deposits += nervos_dao_deposit_cell.capacity

memo + nervos_dao_deposit_cell.capacity * (ended_at - nervos_dao_deposit_cell.block_timestamp) / milliseconds_in_day
end
memo + nervos_dao_deposit_cell.capacity * (ended_at - nervos_dao_deposit_cell.block_timestamp) / milliseconds_in_day
end

(sum_interest_bearing + sum_uninterest_bearing) / (interest_bearing_deposits + uninterest_bearing_deposits)
end
Expand Down
2 changes: 1 addition & 1 deletion app/workers/charts/forked_event_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ def perform
forked_events.update_all(status: "processed")
end
end
end
end
25 changes: 13 additions & 12 deletions config/initializers/rack_attack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,17 @@ class Rack::Attack
# ['']] # body
# end
#
self.throttled_response = lambda do |env|
match_data = env["rack.attack.match_data"]
now = match_data[:epoch_time]

headers = {
"RateLimit-Limit" => match_data[:limit].to_s,
"RateLimit-Remaining" => "0",
"RateLimit-Reset" => (now + (match_data[:period] - now % match_data[:period])).to_s
}

[429, headers, ["Throttled\n"]]
end
self.throttled_response =
lambda do |env|
match_data = env["rack.attack.match_data"]
now = match_data[:epoch_time]

headers = {
"RateLimit-Limit" => match_data[:limit].to_s,
"RateLimit-Remaining" => "0",
"RateLimit-Reset" => (now + (match_data[:period] - now % match_data[:period])).to_s
}

[429, headers, ["Throttled\n"]]
end
end
21 changes: 21 additions & 0 deletions test/controllers/api/v1/addresses_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class AddressesControllerTest < ActionDispatch::IntegrationTest

test "should return corresponding data with given address hash" do
address = create(:address, :with_lock_script)
address.query_address = address.address_hash
presented_address = AddressPresenter.new(address)

valid_get api_v1_address_url(address.address_hash)
Expand Down Expand Up @@ -113,6 +114,26 @@ class AddressesControllerTest < ActionDispatch::IntegrationTest
valid_get api_v1_address_url(address.address_hash)
assert_nil json.dig("data", "attributes", "special_address")
end

test "should support full address query when short address's lock script exists" do
address = create(:address, :with_lock_script, address_hash: "ckb1qyqt8xaupvm8837nv3gtc9x0ekkj64vud3jqfwyw5v")
query_key = "ckb1qjda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xw3vumhs9nvu786dj9p0q5elx66t24n3kxgj53qks"
address.query_address = query_key
presented_address = AddressPresenter.new(address)
valid_get api_v1_address_url(query_key)

assert_equal AddressSerializer.new(presented_address).serialized_json, response.body
end

test "should support short address query when full address's lock script exists" do
address = create(:address, :with_lock_script, address_hash: "ckb1qjda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xw3vumhs9nvu786dj9p0q5elx66t24n3kxgj53qks")
query_key = "ckb1qyqt8xaupvm8837nv3gtc9x0ekkj64vud3jqfwyw5v"
address.query_address = query_key
presented_address = AddressPresenter.new(address)
valid_get api_v1_address_url(query_key)

assert_equal AddressSerializer.new(presented_address).serialized_json, response.body
end
end
end
end
Loading

0 comments on commit b95b223

Please sign in to comment.