Skip to content

Commit

Permalink
feat(hapi): add a worker to retrieve the rewards in fio blockchain
Browse files Browse the repository at this point in the history
  • Loading branch information
Torresmorah committed Jul 26, 2024
1 parent b398fdc commit c7d8ad0
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 18 deletions.
120 changes: 111 additions & 9 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 @@ -251,6 +258,101 @@ 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)

await updateRewards(producers)

const scheduleTime = await getLastPaidScheduleTime()

scheduleTime.setSeconds(scheduleTime.getSeconds() + 86400)

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

setTimeout(syncRewards, nextScheduleUpdate)
}

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

0 comments on commit c7d8ad0

Please sign in to comment.