Skip to content

Commit

Permalink
add staking data
Browse files Browse the repository at this point in the history
  • Loading branch information
wuminzhe committed Aug 22, 2023
1 parent a0f82be commit 31d9f38
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 215 deletions.
188 changes: 108 additions & 80 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ require './src/track-goerli'
require './src/track-pangolin'
require './src/storage'
require './src/account'
require './src/supply/ring'
require './src/supply/kton'
require './config/config'
config = get_config

Expand Down Expand Up @@ -38,6 +40,15 @@ task :update_nominees_loop do
end
end

task :update_staking_data_loop do
loop_do do
Rake::Task['gen_staking_data'].reenable
Rake::Task['gen_staking_data'].invoke('darwinia')
Rake::Task['gen_staking_data'].reenable
Rake::Task['gen_staking_data'].invoke('crab')
end
end

##########################################
# Darwinia
##########################################
Expand Down Expand Up @@ -73,92 +84,109 @@ task :update_pangolin_metadata do
end

##########################################
# Goerli <> pangolin
# Multi networks
##########################################
task :update_goerli_pangolin_messages do
track_goerli
end

task :update_pangolin_goerli_messages do
track_pangolin
end

require 'logger'
task :update_nominees, [:network_name] do |_t, args|
logger = Logger.new($stdout)
logger.level = Logger::DEBUG

network_name = args[:network_name]
logger.debug "updating #{network_name} nominees..."

rpc = config["#{network_name}_rpc".to_sym]
metadata = JSON.parse(File.read(config[:metadata][network_name.to_sym]))

ring_pool = get_storage(rpc, metadata, 'darwinia_staking', 'ring_pool', nil, nil)
kton_pool = get_storage(rpc, metadata, 'darwinia_staking', 'kton_pool', nil, nil)
nominee_commissions = get_nominee_commissions(rpc, metadata)
collators = get_collators(rpc, metadata)

# 1. Get all nominators with their nominees
# ---------------------------------------
# { nominator: nominee }
nominators =
get_storage(
rpc,
metadata,
'darwinia_staking',
'nominators',
nil,
nil
)

nominator_nominee_mapping =
nominators.map do |item|
nominator_address = "0x#{item[:storage_key][-40..]}"
nominee_address = item[:storage].to_hex
[nominator_address, nominee_address]
timed do
network_name = args[:network_name]
logger.debug "updating #{network_name} nominees..."

rpc = config["#{network_name}_rpc".to_sym]
metadata = JSON.parse(File.read(config[:metadata][network_name.to_sym]))

ring_pool = get_storage(rpc, metadata, 'darwinia_staking', 'ring_pool', nil, nil)
kton_pool = get_storage(rpc, metadata, 'darwinia_staking', 'kton_pool', nil, nil)
nominee_commissions = get_nominee_commissions(rpc, metadata)
collators = get_collators(rpc, metadata)

# 1. Get all nominators with their nominees
# ---------------------------------------
# { nominator: nominee }
nominators =
get_storage(
rpc,
metadata,
'darwinia_staking',
'nominators',
nil,
nil
)

nominator_nominee_mapping =
nominators.map do |item|
nominator_address = "0x#{item[:storage_key][-40..]}"
nominee_address = item[:storage].to_hex
[nominator_address, nominee_address]
end.to_h

# 2. Get all nominators' staking info
# ---------------------------------------
# {
# "nominator" => {:staked_ring=>10000000000000000000, :staked_kton=>0},
# }
nominator_addresses = nominator_nominee_mapping.keys
nominator_staking_infos = get_accounts_staking_info(rpc, metadata, nominator_addresses)

# 3. Sum up nominators' staking info of each nominee
# ---------------------------------------
# {
# "nominee" => {:staked_ring=>total, :staked_kton=>total},
# }
result =
nominator_addresses.each_with_object({}) do |nominator_address, acc|
nominator_staking_info = nominator_staking_infos[nominator_address]
nominee_address = nominator_nominee_mapping[nominator_address]
acc[nominee_address] =
{
staked_ring: (acc[nominee_address]&.[](:staked_ring) || 0) + nominator_staking_info[:staked_ring],
staked_kton: (acc[nominee_address]&.[](:staked_kton) || 0) + nominator_staking_info[:staked_kton]
}
end

# 4. Calculate power of each nominee
# ---------------------------------------
nominee_powers = result.map do |nominee_address, staking_info|
power = calc_power(staking_info[:staked_ring], staking_info[:staked_kton], ring_pool, kton_pool)
[nominee_address, power]
end.to_h

# 5. Set the collators committee
# ---------------------------------------
result = nominee_powers.keys.map do |key|
[key, { power: nominee_powers[key], commission: nominee_commissions[key], is_collator: collators.include?(key) }]
end.to_h
# logger.debug JSON.pretty_generate(result)

# 2. Get all nominators' staking info
# ---------------------------------------
# {
# "nominator" => {:staked_ring=>10000000000000000000, :staked_kton=>0},
# }
nominator_addresses = nominator_nominee_mapping.keys
nominator_staking_infos = get_accounts_staking_info(rpc, metadata, nominator_addresses)

# 3. Sum up nominators' staking info of each nominee
# ---------------------------------------
# {
# "nominee" => {:staked_ring=>total, :staked_kton=>total},
# }
result =
nominator_addresses.each_with_object({}) do |nominator_address, acc|
nominator_staking_info = nominator_staking_infos[nominator_address]
nominee_address = nominator_nominee_mapping[nominator_address]
acc[nominee_address] =
{
staked_ring: (acc[nominee_address]&.[](:staked_ring) || 0) + nominator_staking_info[:staked_ring],
staked_kton: (acc[nominee_address]&.[](:staked_kton) || 0) + nominator_staking_info[:staked_kton]
}
end

# 4. Calculate power of each nominee
# ---------------------------------------
nominee_powers = result.map do |nominee_address, staking_info|
power = calc_power(staking_info[:staked_ring], staking_info[:staked_kton], ring_pool, kton_pool)
[nominee_address, power]
end.to_h

# 5. Set the collators committee
# ---------------------------------------
result = nominee_powers.keys.map do |key|
[key, { power: nominee_powers[key], commission: nominee_commissions[key], is_collator: collators.include?(key) }]
end.to_h
logger.debug JSON.pretty_generate(result)

# 6. write to file
# ---------------------------------------
logger.debug "writing #{network_name} nominees to file..."
write_data_to_file(result, "#{network_name}-nominees.json")
# 6. write to file
# ---------------------------------------
logger.debug "writing #{network_name} nominees to file..."
write_data_to_file(result, "#{network_name}-nominees.json")
end
end

task :gen_staking_data, [:network_name] do |_t, args|
timed do
network_name = args[:network_name]
puts "generate #{network_name} staking data..."

rpc = config["#{network_name}_rpc".to_sym]
metadata = JSON.parse(File.read(config[:metadata][network_name.to_sym]))

result = {
ring: {
staking: get_all_staking_ring(rpc, metadata),
unmigrated: get_all_staking_ring_unmigrated(rpc, metadata)
},
kton: {
staking: get_staking_kton(rpc, metadata),
unmigrated: get_staking_kton_unmigrated(rpc, metadata)
}
}

write_data_to_file(result, "#{network_name}-staking.json")
end
end
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ services:
command: rake update_nominees_loop
volumes:
- ./data:/usr/src/app/data
update_staking:
build: .
env_file:
- .env
command: rake update_staking_data_loop
volumes:
- ./data:/usr/src/app/data
server:
build: .
env_file:
Expand Down
14 changes: 14 additions & 0 deletions src/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,20 @@
##############################################################################
# General
##############################################################################
get '/:network/staking' do
network = params[:network].downcase
unless %w[darwinia crab pangolin].include?(network)
raise_with 404,
"network #{network} not found, only `darwinia`, `crab` and `pangolin` are supported"
end

result = File.read("./data/#{network}-staking.json")
result = JSON.parse(result)

content_type :json
{ code: 0, data: result }.to_json
end

get '/:network/nominees' do
network = params[:network].downcase
unless %w[darwinia crab pangolin].include?(network)
Expand Down
48 changes: 24 additions & 24 deletions src/supplies.rb
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@
require "scale_rb"
require "eth"
require "json"
require 'scale_rb'
require 'eth'
require 'json'
include Eth
require_relative "supply/ring"
require_relative "supply/kton"
require_relative "./utils"
require_relative "account"
require_relative 'supply/ring'
require_relative 'supply/kton'
require_relative './utils'
require_relative 'account'

def calc_ring_supply(ethereum_rpc, darwinia_rpc, metadata)
total_issuance = get_total_insurance(darwinia_rpc, metadata)

darwinia_client = Eth::Client::Http.new(darwinia_rpc)
ethereum_client = Eth::Client::Http.new(ethereum_rpc)

# Reserve on Darwinia Chain
reserve = get_account_info(darwinia_rpc, metadata, "0x081cbab52e2dBCd52F441c7ae9ad2a3BE42e2284")[:ring].to_i
reserve = get_account_info(darwinia_rpc, metadata, '0x081cbab52e2dBCd52F441c7ae9ad2a3BE42e2284')[:ring].to_i
puts "reserve: #{reserve}"

# Ecosystem Development Fund
token_contract = "0x9469D013805bFfB7D3DEBe5E7839237e535ec483"
token_contract = '0x9469D013805bFfB7D3DEBe5E7839237e535ec483'
# Financing
financing_address = "0xfa4fe04f69f87859fcb31df3b9469f4e6447921c"
financing_address = '0xfa4fe04f69f87859fcb31df3b9469f4e6447921c'
data = "0x70a08231000000000000000000000000#{financing_address[2..]}"
financing =
ethereum_client.eth_call({ to: token_contract, data: data })["result"].to_i(
16,
ethereum_client.eth_call({ to: token_contract, data: })['result'].to_i(
16
).to_f / 10**18

# BD & Marketing
bd_marketing_address = "0x5FD8bCC6180eCd977813465bDd0A76A5a9F88B47"
bd_marketing_address = '0x5FD8bCC6180eCd977813465bDd0A76A5a9F88B47'
data = "0x70a08231000000000000000000000000#{bd_marketing_address[2..]}"
bd_marketing =
ethereum_client.eth_call({ to: token_contract, data: data })["result"].to_i(
16,
).to_f / 10**18
ethereum_client.eth_call({ to: token_contract, data: })['result'].to_i(
16
).to_f / 10**18
puts "financing: #{financing}, bd_marketing: #{bd_marketing}"

ecosystem_development_fund = financing + bd_marketing

# Treasury
treasury_address = "0x6d6f646c64612f74727372790000000000000000"
treasury_address = '0x6d6f646c64612f74727372790000000000000000'
treasury =
darwinia_client.eth_get_balance(treasury_address)["result"].to_i(16).to_f / 10**18
darwinia_client.eth_get_balance(treasury_address)['result'].to_i(16).to_f / 10**18
puts "treasury: #{treasury}"

circulating_supply = total_issuance - (reserve + ecosystem_development_fund + treasury).to_i
Expand All @@ -50,7 +50,7 @@ def calc_ring_supply(ethereum_rpc, darwinia_rpc, metadata)
{
totalSupply: total_issuance,
circulatingSupply: circulating_supply,
maxSupply: 10_000_000_000,
maxSupply: 10_000_000_000
}
end

Expand All @@ -60,25 +60,25 @@ def calc_kton_supply(rpc, metadata)
{
totalSupply: total_issuance,
circulatingSupply: total_issuance,
maxSupply: total_issuance,
maxSupply: total_issuance
}
end

def calc_supply(ethereum_rpc, darwinia_rpc, metadata)
{
ringSupplies: calc_ring_supply(ethereum_rpc, darwinia_rpc, metadata),
ktonSupplies: calc_kton_supply(darwinia_rpc, metadata),
ktonSupplies: calc_kton_supply(darwinia_rpc, metadata)
}
end

def generate_supplies(network_name, ethereum_rpc, darwinia_rpc, metadata)
puts "generating #{network_name} supplies data..."
timed do
data_dir = "./data"
data_dir = './data'
FileUtils.mkdir_p(data_dir) unless File.directory?(data_dir)
File.write(
File.join(data_dir, "#{network_name}-supplies.json"),
calc_supply(ethereum_rpc, darwinia_rpc, metadata).to_json,
calc_supply(ethereum_rpc, darwinia_rpc, metadata).to_json
)
end
end
Expand Down
Loading

0 comments on commit 31d9f38

Please sign in to comment.