Skip to content

Commit

Permalink
cache validator counter
Browse files Browse the repository at this point in the history
  • Loading branch information
classicalliu committed Sep 3, 2018
1 parent 1c794f6 commit 91efc85
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 3 deletions.
5 changes: 3 additions & 2 deletions app/controllers/api/statistics_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ def index
# }
# ]
def proposals
result = Block.where.not(block_number: 0).group("header ->> 'proposer'").count
.map { |k, v| { validator: k, count: v } }
# result = Block.where.not(block_number: 0).group("header ->> 'proposer'").count
# .map { |k, v| { validator: k, count: v } }
result = ValidatorCache.all.map { |c| { validator: c.name, count: c.counter } }

render json: {
result: result
Expand Down
10 changes: 10 additions & 0 deletions app/models/block.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,20 @@ class Block < ApplicationRecord

store_accessor :header, :timestamp

after_create :increase_validator_count

# get current last block number in database
#
# @return [Integer, nil] the current last block number or nil if no block found in db.
def self.current_block_number
Block.order(block_number: :desc).first&.block_number
end

private

# increase validator count after block create
def increase_validator_count
return if self.block_number.zero?
ValidatorCache.increase(self.header["proposer"])
end
end
22 changes: 22 additions & 0 deletions app/models/validator_cache.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class ValidatorCache < ApplicationRecord
validates :name, presence: true, uniqueness: true

# increase a validator's count
#
# @param name [String] Block header proposer
# @return [void]
def self.increase(name)
# add transaction for lock cache
ApplicationRecord.transaction do
return if name.blank?
cache = ValidatorCache.find_by(name: name)
if cache.nil?
ValidatorCache.create(name: name, counter: 1)
else
# lock it
cache.lock!
cache.update!(counter: cache.counter + 1)
end
end
end
end
23 changes: 23 additions & 0 deletions db/migrate/20180903024536_create_validator_caches.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class CreateValidatorCaches < ActiveRecord::Migration[5.2]
def change
create_table :validator_caches do |t|
t.string :name, null: false, index: { unique: true }
t.integer :counter

t.timestamps
end

reversible do |dir|
dir.up do
# create validator cache for present blocks
ApplicationRecord.transaction do
Block.where.not(block_number: 0).group("header ->> 'proposer'").count.each do |k, v|
cache = ValidatorCache.find_or_create_by(name: k)
cache.lock!
cache.update(counter: v)
end
end
end
end
end
end
10 changes: 9 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2018_08_30_054052) do
ActiveRecord::Schema.define(version: 2018_09_03_024536) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -83,4 +83,12 @@
t.index ["cita_hash"], name: "index_transactions_on_cita_hash", unique: true
end

create_table "validator_caches", force: :cascade do |t|
t.string "name", null: false
t.integer "counter"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["name"], name: "index_validator_caches_on_name", unique: true
end

end
5 changes: 5 additions & 0 deletions spec/factories/validator_caches.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FactoryBot.define do
factory :validator_cache, class: 'ValidatorCache' do
name "0x91827976af27e1fd405469b00dc8d3b0ea2203f6"
end
end
18 changes: 18 additions & 0 deletions spec/models/block_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,22 @@
expect(Block.current_block_number).to eq block.block_number
end
end

context "after create" do
context "increase_validator_count" do
it "not cache if block_number.zero?" do
block = create :block_zero, block_number: 0
proposer = block.header['proposer']
expect(proposer.blank?).not_to be true
expect(ValidatorCache.exists?(name: proposer)).to be false
end

it "cache if block_number not eq zero" do
block = create :block_one, block_number: 1
proposer = block.header["proposer"]
expect(proposer.blank?).not_to be true
expect(ValidatorCache.find_by(name: proposer).counter).to eq 1
end
end
end
end
26 changes: 26 additions & 0 deletions spec/models/validator_cache_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require 'rails_helper'

RSpec.describe ValidatorCache, type: :model do
let(:proposer) { attributes_for(:validator_cache)[:name] }

context "increase" do
it "counter be 1 if not exist" do
expect(ValidatorCache.exists?(name: proposer)).to be false
expect {
ValidatorCache.increase(proposer)
}.to change { ValidatorCache.count }.by(1)
cache = ValidatorCache.find_by(name: proposer)
expect(cache.counter).to eq 1
end

it "counter add 1 if exist" do
counter = 5
create :validator_cache, counter: counter
expect {
ValidatorCache.increase(proposer)
}.to change { ValidatorCache.count }.by(0)
cache = ValidatorCache.find_by(name: proposer)
expect(cache.counter).to eq (counter + 1)
end
end
end

0 comments on commit 91efc85

Please sign in to comment.