Skip to content

Commit

Permalink
Merge pull request #1427 from edenia/dev
Browse files Browse the repository at this point in the history
Production Release
  • Loading branch information
xavier506 committed Jul 31, 2024
2 parents d0898b8 + d3f62ce commit ecef97d
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy-fio-testnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
POSTGRES_DB: ${{ secrets.POSTGRES_DB }}
POSTGRES_DATA: ${{ secrets.POSTGRES_DATA }}
# hapi
HAPI_EOS_API_NETWORK_NAME: fio-testnet
HAPI_EOS_API_NETWORK_NAME: fio
HAPI_EOS_API_ENDPOINTS: '["https://testnet.fioprotocol.io","https://fio-testnet.eosphere.io"]'
HAPI_EOS_STATE_HISTORY_PLUGIN_ENDPOINT: ''
HAPI_EOS_MISSED_BLOCKS_ENABLED: 'false'
Expand Down
136 changes: 126 additions & 10 deletions hapi/src/services/fio.service.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
const { StatusCodes } = require('http-status-codes')

const { axiosUtil, eosUtil, sequelizeUtil, producerUtil } = require('../utils')
const { axiosUtil, hasuraUtil, eosUtil, sequelizeUtil, producerUtil } = require('../utils')
const { eosConfig } = require('../config')

const MAX_PAID_PRODUCERS = 42

const updateRewards = async (producers = []) => {
const upsertMutation = `
mutation ($producers: [producer_insert_input!]!) {
insert_producer(objects: $producers, on_conflict: {constraint: producer_owner_key, update_columns: [ vote_rewards, block_rewards, total_rewards ]}) {
affected_rows,
}
}
`

await hasuraUtil.request(upsertMutation, { producers })
}

const getProducers = async () => {
let producers = []
let totalVoteWeight
Expand Down Expand Up @@ -60,16 +74,9 @@ const getProducers = async () => {
return 0
})

const rewards = await producerUtil.getExpectedRewards(
producers,
totalVoteWeight
)
const nonPaidStandby = { vote_rewards: 0, block_rewards: 0, total_rewards: 0 }

producers = producers.map((producer, index) => {
return {
owner: producer.owner,
...(rewards[producer.owner] || nonPaidStandby),
total_votes: producer.total_votes,
total_votes_percent: producer.total_votes / totalVoteWeight,
total_votes_eos: producerUtil.getVotes(producer.total_votes),
Expand Down Expand Up @@ -187,7 +194,7 @@ const getChains = async producerUrl => {
}

const isNonCompliant = producer => {
return !Object.keys(producer.bpJson).length && producer.total_rewards >= 100
return !Object.keys(producer.bpJson).length && producer.total_rewards > 0
}

const getProducerHealthStatus = async producer => {
Expand Down Expand Up @@ -251,6 +258,115 @@ const getProducersFromDB = async () => {
return producers
}

const getVoteShares = async () => {
try {
const { rows } = await eosUtil.getTableRows({
code: 'fio.treasury',
scope: 'fio.treasury',
table: 'voteshares',
reverse: false,
limit: MAX_PAID_PRODUCERS,
json: true,
lower_bound: null
})

if (!Array.isArray(rows)) return []

return rows
} catch (error) {
console.warn('SYNC FIO REWARDS', error.message || error)

return []
}
}

const getFioRewards = async (producers, voteShares) => {
const activeProducers = producers.slice(0, MAX_PAID_PRODUCERS)

return voteShares.flatMap(producer => {
if (activeProducers.find(bp => bp.owner === producer.owner)) {
const expectedVoteReward = producer.abpayshare / 10 ** 9
const expectedBlockReward = producer.sbpayshare / 10 ** 9

return ({
owner: producer.owner,
vote_rewards: expectedVoteReward,
block_rewards: expectedBlockReward,
total_rewards: expectedVoteReward + expectedBlockReward
})
}

return []
})
}

const getProducersWithRewards = async (voteShares) => {
const producers = await getProducersFromDB()
const paidProducers = await getFioRewards(producers.slice(0, MAX_PAID_PRODUCERS), voteShares)
const nonPaidStandby =
producers.slice(MAX_PAID_PRODUCERS).map(producer => ({
owner: producer.owner,
vote_rewards: 0,
block_rewards: 0,
total_rewards: 0
}))

return paidProducers.concat(nonPaidStandby)
}

const getLastPaidScheduleTime = async () => {
try {
const { rows } = await eosUtil.getTableRows({
code: 'fio.treasury',
scope: 'fio.treasury',
table: 'clockstate',
reverse: false,
limit: 1,
json: true,
lower_bound: null
})

if (!rows?.at(0)?.payschedtimer) return

return new Date(rows?.at(0)?.payschedtimer * 1000)
} catch (error) {
console.warn('SYNC FIO REWARDS', error.message || error)
}
}

// Every day the `voteshare` table is populated with the rewards the BP can claim that day.
const syncRewards = async () => {
console.log('SYNCING FIO REWARDS')

const voteShares = await getVoteShares()
const producers = await getProducersWithRewards(voteShares)

if (!producers?.length) {
setTimeout(syncRewards, 2 * 60 * 1000)
} else {
await updateRewards(producers)

const scheduleTime = await getLastPaidScheduleTime()
const scheduleTimeMs = scheduleTime?.getTime() || 0

if (scheduleTimeMs > 0) {
scheduleTime.setSeconds(scheduleTime.getSeconds() + 86400)

const nextScheduleUpdate = Math.ceil((scheduleTime.getTime() - (new Date()).getTime()))

if (nextScheduleUpdate > 0) {
console.log(`SYNCING FIO REWARDS - sync completed, next sync on ${scheduleTime.toISOString()}`)
setTimeout(syncRewards, nextScheduleUpdate)
} else {
setTimeout(syncRewards, 5 * 60 * 1000)
}
} else {
setTimeout(syncRewards, 60 * 1000)
}
}
}

module.exports = {
getProducers
getProducers,
syncRewards
}
2 changes: 2 additions & 0 deletions hapi/src/services/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const cpuService = require('./cpu.service')
const missedBlocksService = require('./missed-blocks.service')
const producerService = require('./producer.service')
const fioService = require('./fio.service')
const nodeService = require('./node.service')
const healthCheckHistoryService = require('./health-check-history.service')
const settingService = require('./setting.service')
Expand All @@ -14,6 +15,7 @@ module.exports = {
cpuService,
missedBlocksService,
producerService,
fioService,
nodeService,
healthCheckHistoryService,
settingService,
Expand Down
4 changes: 3 additions & 1 deletion hapi/src/services/producer.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ const updateBPJSONs = async (producers = []) => {
}

const updateProducers = async (producers = []) => {
const includeRewards = eosConfig.networkName !== eosConfig.knownNetworks.fio
const additionalFields = includeRewards ? 'vote_rewards, block_rewards, total_rewards' : ''
const upsertMutation = `
mutation ($producers: [producer_insert_input!]!) {
insert_producer(objects: $producers, on_conflict: {constraint: producer_owner_key, update_columns: [ producer_key, unpaid_blocks,last_claim_time, url, location, producer_authority, is_active, total_votes, total_votes_percent, total_votes_eos, vote_rewards,block_rewards, total_rewards, endpoints, rank, bp_json_url, fio_address, addresshash, last_bpclaim]}) {
insert_producer(objects: $producers, on_conflict: {constraint: producer_owner_key, update_columns: [ producer_key, unpaid_blocks,last_claim_time, url, location, producer_authority, is_active, total_votes, total_votes_percent, total_votes_eos, endpoints, rank, bp_json_url, fio_address, addresshash, last_bpclaim, ${additionalFields}]}) {
affected_rows,
returning {
id,
Expand Down
7 changes: 0 additions & 7 deletions hapi/src/utils/producer.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ const getExpectedRewards = async (producers, totalVotes) => {
rewards = await getTelosRewards(producers)
break
case eosConfig.knownNetworks.fio:
rewards = await getFioRewards(producers)
break
default:
rewards = await getEOSIORewards(producers, totalVotes)
Expand Down Expand Up @@ -281,12 +280,6 @@ const getEOSIORewards = async (producers, totalVotes) => {
return producersRewards
}

const getFioRewards = async (producers) => {
const producersRewards = []
// ToDo : Calculate producer Rewards Based on FIO System Contracts
return producersRewards
}

const getVotes = (votes) => {
switch (eosConfig.networkName) {
case eosConfig.knownNetworks.telos:
Expand Down
10 changes: 9 additions & 1 deletion hapi/src/workers/producers.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const {
producerService,
settingService,
stateHistoryPluginService,
statsService
statsService,
fioService,
} = require('../services')
const { workersConfig, hasuraConfig, eosConfig } = require('../config')
const { axiosUtil, sleepFor } = require('../utils')
Expand Down Expand Up @@ -59,6 +60,13 @@ const start = async () => {
workersConfig.syncExchangeRate
)

if (eosConfig.networkName === eosConfig.knownNetworks.fio) {
run(
'SYNC FIO REWARDS',
fioService.syncRewards
)
}

if (eosConfig.eosmechanics.account && eosConfig.eosmechanics.password) {
run('CPU WORKER', cpuService.worker, workersConfig.cpuWorkerInterval)
run('CPU WORKER CLEANUP', cpuService.cleanOldBenchmarks, 86400)
Expand Down
4 changes: 3 additions & 1 deletion webapp/src/hooks/customHooks/useBlockProducerState.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { eosConfig } from '../../config'

import useSearchState from './useBPSearchState'

const isFIO = eosConfig.networkName.replace('-testnet', '') === 'fio'
const minimumRewards = isFIO ? 1 : 100
const CHIPS_FILTERS = [
{ where: { owner: { _like: '%%' }, bp_json: { _is_null: false } } },
{
where: { total_rewards: { _neq: 0 }, rank: { _lte: 21 } },
},
{
where: { total_rewards: { _gte: 100 }, rank: { _gte: 22 } },
where: { total_rewards: { _gte: minimumRewards }, rank: { _gte: 22 } },
},
{
where: { total_rewards: { _eq: 0 } },
Expand Down
8 changes: 6 additions & 2 deletions webapp/src/hooks/customHooks/useNonCompliantState.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,27 @@ import { useLazyQuery } from '@apollo/client'

import { PRODUCERS_QUERY, SETTING_QUERY } from '../../gql'

import { eosConfig } from 'config'

const useNonCompliantState = () => {
const [loadProducers, { loading = true, data: { producers } = {} }] =
useLazyQuery(PRODUCERS_QUERY)
const [loadSettings, { data: { setting } = {} }] = useLazyQuery(SETTING_QUERY)
const [items, setItems] = useState([])
const [stats, setStats] = useState()
const isFIO = eosConfig.networkName.replace('-testnet', '') === 'fio'
const minimumRewards = isFIO ? 1 : 100

useEffect(() => {
loadSettings({})
loadProducers({
variables: {
where: { total_rewards: { _gte: 100 } },
where: { total_rewards: { _gte: minimumRewards } },
offset: 0,
limit: 150,
},
})
}, [loadSettings, loadProducers])
}, [loadSettings, loadProducers, minimumRewards])

useEffect(() => {
if (!producers) return
Expand Down
10 changes: 7 additions & 3 deletions webapp/src/hooks/customHooks/useRewardsDistributionState.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import { useState, useEffect } from 'react'
import { useLazyQuery } from '@apollo/client'

import { countries } from 'utils/countries'
import { PRODUCERS_QUERY, SETTING_QUERY } from '../../gql'

import { countries } from 'utils/countries'
import { eosConfig } from 'config'

const useRewardsDistributionState = () => {
const [loadSettings, { data: { setting } = {} }] = useLazyQuery(SETTING_QUERY)
const [loadProducers, { loading = true, data: { producers } = {} }] =
useLazyQuery(PRODUCERS_QUERY)
const [summary, setSummary] = useState()
const [items, setItems] = useState([])
const isFIO = eosConfig.networkName.replace('-testnet', '') === 'fio'
const minimumRewards = isFIO ? 1 : 100

useEffect(() => {
loadSettings({})
loadProducers({
variables: {
where: { total_rewards: { _gte: 100 } },
where: { total_rewards: { _gte: minimumRewards } },
offset: 0,
limit: 2100,
},
})
}, [loadSettings, loadProducers])
}, [loadSettings, loadProducers, minimumRewards])

useEffect(() => {
if (!producers) return
Expand Down

0 comments on commit ecef97d

Please sign in to comment.