Skip to content

Commit

Permalink
release (#223)
Browse files Browse the repository at this point in the history
* fixed a bug where a single proposal would not load (#125)

* trigger ci

* fixed missing terra data source (#128)

* Fabo/fix missing terra db query (#130)

* fixed missing terra data source

* fixed missing query

* Fabo/fix failing staking query for terra (#132)

* fixed missing terra data source

* fixed missing query

* fix bech32 prefix in selfStake resolver

* linted

* Fabo/hide proposals on terra (#134)

* fixed missing terra data source

* fixed missing query

* fix bech32 prefix in selfStake resolver

* linted

* don't show proposals on terra

* Fabo/switch to yarn (#122)

* switch to yarn

* Update Readme

* Ana/111 regen testnet production (#118)

* regen is home

* fix websocket link

* eslint fix

* delete console logs

* fixed regen source (using cosmosV0)

* add feature flags for regen

* fix txs in regen

* fix transactions per address

* fix eslint errors

* disable sign in

* colw/Transaction Service (#120)

* Obtain transaction payload, mirror back to client

* Respond with request, or error if none present

* Load node friendly versions of cosmos-api for dev

* Send response as JSON

* Successfully retrieve a gas estimate

- Use node-fetch for cosmosAPIs
-

* Add two sub routes: /estimate and /broadcast

* Add account number and sequence to overview query

* Disable cors options

* Add support to broadcast messages

* Ignore fetch undefined

* Delete package-lock.json

* Fabo/simplify queries (#108)

* simplified db queries

Conflicts:
	lib/luniedb-source.js
	lib/queries.js

* switched to yarn

* clean up

* clean up

* Copy cosmos libraries into container (#143)

* Aleksei/terra url change (#144)

* terra url changed

* change soju-0010 to soju-0012

* fixed db queries (#147)

* Update networks.json (#149)

* Fabo/events (#123)

* first steps

* working notification endpoint

* remove push mentions

* linted

* fixes

* updated schema

* use enum for eventtype

* working subscription

* linted

* added push to express routes

* remove newer code

* linted

* Update lib/routes/push.js

Co-Authored-By: Col <[email protected]>

* disable session for regen (#155)

* Aleksei/terra url change (#146)

* terra url changed

* change soju-0010 to soju-0012

* cors added to caddyfiles

* cors added to caddyfiles

* fix missing path

* Fabo/fix vote count (#157)

* fixed vote count calculation

* linted

* Ana/handle with message proposal id error (#159)

* handle undefined proposal error

* fix lint errors

* Ana/add endtime to undelegation tx (#150)

* add liquiddate as field for tx

* fix eslint errors

* change name liquidDate to undelegationEndTime

* fix enddelegationtime for gaia

* improve reducer my way

* fix lint error

* move undelegationendtime to reducer

* fix lint errors

* no abbreviations

* implement undelegation endtime reducer in both

* reenable session for gaia 13006 (#165)

* Ana/fix terra undelegationendtime reducer (#162)

* change reducers to cosmosV2

* prevent result undefined error

* add own gettransaction and txreducer for terra

* fix terra undelegationendtime reducer

* fix lint errors

* avoid hardcoded indexes

* small fix to prevent total server error

* no redundancy: add reducers to transactionreducer

* fix lint

* trigger CI

* Don't return delegations with dust amounts (#171)

* Add filter to delegations

* Fix filter

* Simplify

* add undelegations to total stake (#174)

* Terra chain_id switched to soju-0013 (#176)

* terra chaind_id switched to soju-0013

* changed terra node

* fix issues with undelegatio end time (#175)

* Fabo/fix undelegationendtime (#177)

* fix issues with undelegatio end time

* catch undelegation attribute not found

* Fabo/fix undelegationendtime for regen (#178)

* fix issues with undelegatio end time

* catch undelegation attribute not found

* fix regen transaction reducers

* Display Deposit Period End Date correctly for proposals in deposit period (#181)

* Return proposal.voting_end_time in deposit period

* Return deposit_end_time instead

* update to new reducers and chain-id (#182)

* merge back (#186)

* release (#179)

* fixed a bug where a single proposal would not load (#125)

* trigger ci

* fixed missing terra data source (#128)

* Fabo/fix missing terra db query (#130)

* fixed missing terra data source

* fixed missing query

* Fabo/fix failing staking query for terra (#132)

* fixed missing terra data source

* fixed missing query

* fix bech32 prefix in selfStake resolver

* linted

* Fabo/hide proposals on terra (#134)

* fixed missing terra data source

* fixed missing query

* fix bech32 prefix in selfStake resolver

* linted

* don't show proposals on terra

* Fabo/switch to yarn (#122)

* switch to yarn

* Update Readme

* Ana/111 regen testnet production (#118)

* regen is home

* fix websocket link

* eslint fix

* delete console logs

* fixed regen source (using cosmosV0)

* add feature flags for regen

* fix txs in regen

* fix transactions per address

* fix eslint errors

* disable sign in

* colw/Transaction Service (#120)

* Obtain transaction payload, mirror back to client

* Respond with request, or error if none present

* Load node friendly versions of cosmos-api for dev

* Send response as JSON

* Successfully retrieve a gas estimate

- Use node-fetch for cosmosAPIs
-

* Add two sub routes: /estimate and /broadcast

* Add account number and sequence to overview query

* Disable cors options

* Add support to broadcast messages

* Ignore fetch undefined

* Delete package-lock.json

* Fabo/simplify queries (#108)

* simplified db queries

Conflicts:
	lib/luniedb-source.js
	lib/queries.js

* switched to yarn

* clean up

* clean up

* Copy cosmos libraries into container (#143)

* Aleksei/terra url change (#144)

* terra url changed

* change soju-0010 to soju-0012

* fixed db queries (#147)

* Update networks.json (#149)

* Fabo/events (#123)

* first steps

* working notification endpoint

* remove push mentions

* linted

* fixes

* updated schema

* use enum for eventtype

* working subscription

* linted

* added push to express routes

* remove newer code

* linted

* Update lib/routes/push.js

Co-Authored-By: Col <[email protected]>

* disable session for regen (#155)

* Aleksei/terra url change (#146)

* terra url changed

* change soju-0010 to soju-0012

* cors added to caddyfiles

* cors added to caddyfiles

* fix missing path

* Fabo/fix vote count (#157)

* fixed vote count calculation

* linted

* Ana/handle with message proposal id error (#159)

* handle undefined proposal error

* fix lint errors

* Ana/add endtime to undelegation tx (#150)

* add liquiddate as field for tx

* fix eslint errors

* change name liquidDate to undelegationEndTime

* fix enddelegationtime for gaia

* improve reducer my way

* fix lint error

* move undelegationendtime to reducer

* fix lint errors

* no abbreviations

* implement undelegation endtime reducer in both

* reenable session for gaia 13006 (#165)

* Ana/fix terra undelegationendtime reducer (#162)

* change reducers to cosmosV2

* prevent result undefined error

* add own gettransaction and txreducer for terra

* fix terra undelegationendtime reducer

* fix lint errors

* avoid hardcoded indexes

* small fix to prevent total server error

* no redundancy: add reducers to transactionreducer

* fix lint

* trigger CI

* Don't return delegations with dust amounts (#171)

* Add filter to delegations

* Fix filter

* Simplify

* add undelegations to total stake (#174)

* Terra chain_id switched to soju-0013 (#176)

* terra chaind_id switched to soju-0013

* changed terra node

* fix issues with undelegatio end time (#175)

* Fabo/fix undelegationendtime (#177)

* fix issues with undelegatio end time

* catch undelegation attribute not found

* Fabo/fix undelegationendtime for regen (#178)

* fix issues with undelegatio end time

* catch undelegation attribute not found

* fix regen transaction reducers

* Display Deposit Period End Date correctly for proposals in deposit period (#181)

* Return proposal.voting_end_time in deposit period

* Return deposit_end_time instead

* release (#183)

* fixed a bug where a single proposal would not load (#125)

* trigger ci

* fixed missing terra data source (#128)

* Fabo/fix missing terra db query (#130)

* fixed missing terra data source

* fixed missing query

* Fabo/fix failing staking query for terra (#132)

* fixed missing terra data source

* fixed missing query

* fix bech32 prefix in selfStake resolver

* linted

* Fabo/hide proposals on terra (#134)

* fixed missing terra data source

* fixed missing query

* fix bech32 prefix in selfStake resolver

* linted

* don't show proposals on terra

* Fabo/switch to yarn (#122)

* switch to yarn

* Update Readme

* Ana/111 regen testnet production (#118)

* regen is home

* fix websocket link

* eslint fix

* delete console logs

* fixed regen source (using cosmosV0)

* add feature flags for regen

* fix txs in regen

* fix transactions per address

* fix eslint errors

* disable sign in

* colw/Transaction Service (#120)

* Obtain transaction payload, mirror back to client

* Respond with request, or error if none present

* Load node friendly versions of cosmos-api for dev

* Send response as JSON

* Successfully retrieve a gas estimate

- Use node-fetch for cosmosAPIs
-

* Add two sub routes: /estimate and /broadcast

* Add account number and sequence to overview query

* Disable cors options

* Add support to broadcast messages

* Ignore fetch undefined

* Delete package-lock.json

* Fabo/simplify queries (#108)

* simplified db queries

Conflicts:
	lib/luniedb-source.js
	lib/queries.js

* switched to yarn

* clean up

* clean up

* Copy cosmos libraries into container (#143)

* Aleksei/terra url change (#144)

* terra url changed

* change soju-0010 to soju-0012

* fixed db queries (#147)

* Update networks.json (#149)

* Fabo/events (#123)

* first steps

* working notification endpoint

* remove push mentions

* linted

* fixes

* updated schema

* use enum for eventtype

* working subscription

* linted

* added push to express routes

* remove newer code

* linted

* Update lib/routes/push.js

Co-Authored-By: Col <[email protected]>

* disable session for regen (#155)

* Aleksei/terra url change (#146)

* terra url changed

* change soju-0010 to soju-0012

* cors added to caddyfiles

* cors added to caddyfiles

* fix missing path

* Fabo/fix vote count (#157)

* fixed vote count calculation

* linted

* Ana/handle with message proposal id error (#159)

* handle undefined proposal error

* fix lint errors

* Ana/add endtime to undelegation tx (#150)

* add liquiddate as field for tx

* fix eslint errors

* change name liquidDate to undelegationEndTime

* fix enddelegationtime for gaia

* improve reducer my way

* fix lint error

* move undelegationendtime to reducer

* fix lint errors

* no abbreviations

* implement undelegation endtime reducer in both

* reenable session for gaia 13006 (#165)

* Ana/fix terra undelegationendtime reducer (#162)

* change reducers to cosmosV2

* prevent result undefined error

* add own gettransaction and txreducer for terra

* fix terra undelegationendtime reducer

* fix lint errors

* avoid hardcoded indexes

* small fix to prevent total server error

* no redundancy: add reducers to transactionreducer

* fix lint

* trigger CI

* Don't return delegations with dust amounts (#171)

* Add filter to delegations

* Fix filter

* Simplify

* add undelegations to total stake (#174)

* Terra chain_id switched to soju-0013 (#176)

* terra chaind_id switched to soju-0013

* changed terra node

* fix issues with undelegatio end time (#175)

* Fabo/fix undelegationendtime (#177)

* fix issues with undelegatio end time

* catch undelegation attribute not found

* Fabo/fix undelegationendtime for regen (#178)

* fix issues with undelegatio end time

* catch undelegation attribute not found

* fix regen transaction reducers

* Display Deposit Period End Date correctly for proposals in deposit period (#181)

* Return proposal.voting_end_time in deposit period

* Return deposit_end_time instead

* update to new reducers and chain-id (#182)

* Fabo/fix rewards (#185)

* fixed a bug where a single proposal would not load (#125)

* trigger ci

* fixed missing terra data source (#128)

* Fabo/fix missing terra db query (#130)

* fixed missing terra data source

* fixed missing query

* Fabo/fix failing staking query for terra (#132)

* fixed missing terra data source

* fixed missing query

* fix bech32 prefix in selfStake resolver

* linted

* Fabo/hide proposals on terra (#134)

* fixed missing terra data source

* fixed missing query

* fix bech32 prefix in selfStake resolver

* linted

* don't show proposals on terra

* Fabo/switch to yarn (#122)

* switch to yarn

* Update Readme

* Ana/111 regen testnet production (#118)

* regen is home

* fix websocket link

* eslint fix

* delete console logs

* fixed regen source (using cosmosV0)

* add feature flags for regen

* fix txs in regen

* fix transactions per address

* fix eslint errors

* disable sign in

* colw/Transaction Service (#120)

* Obtain transaction payload, mirror back to client

* Respond with request, or error if none present

* Load node friendly versions of cosmos-api for dev

* Send response as JSON

* Successfully retrieve a gas estimate

- Use node-fetch for cosmosAPIs
-

* Add two sub routes: /estimate and /broadcast

* Add account number and sequence to overview query

* Disable cors options

* Add support to broadcast messages

* Ignore fetch undefined

* Delete package-lock.json

* Fabo/simplify queries (#108)

* simplified db queries

Conflicts:
	lib/luniedb-source.js
	lib/queries.js

* switched to yarn

* clean up

* clean up

* Copy cosmos libraries into container (#143)

* Aleksei/terra url change (#144)

* terra url changed

* change soju-0010 to soju-0012

* fixed db queries (#147)

* Update networks.json (#149)

* Fabo/events (#123)

* first steps

* working notification endpoint

* remove push mentions

* linted

* fixes

* updated schema

* use enum for eventtype

* working subscription

* linted

* added push to express routes

* remove newer code

* linted

* Update lib/routes/push.js

Co-Authored-By: Col <[email protected]>

* disable session for regen (#155)

* Aleksei/terra url change (#146)

* terra url changed

* change soju-0010 to soju-0012

* cors added to caddyfiles

* cors added to caddyfiles

* fix missing path

* Fabo/fix vote count (#157)

* fixed vote count calculation

* linted

* Ana/handle with message proposal id error (#159)

* handle undefined proposal error

* fix lint errors

* Ana/add endtime to undelegation tx (#150)

* add liquiddate as field for tx

* fix eslint errors

* change name liquidDate to undelegationEndTime

* fix enddelegationtime for gaia

* improve reducer my way

* fix lint error

* move undelegationendtime to reducer

* fix lint errors

* no abbreviations

* implement undelegation endtime reducer in both

* reenable session for gaia 13006 (#165)

* Ana/fix terra undelegationendtime reducer (#162)

* change reducers to cosmosV2

* prevent result undefined error

* add own gettransaction and txreducer for terra

* fix terra undelegationendtime reducer

* fix lint errors

* avoid hardcoded indexes

* small fix to prevent total server error

* no redundancy: add reducers to transactionreducer

* fix lint

* trigger CI

* Don't return delegations with dust amounts (#171)

* Add filter to delegations

* Fix filter

* Simplify

* add undelegations to total stake (#174)

* Terra chain_id switched to soju-0013 (#176)

* terra chaind_id switched to soju-0013

* changed terra node

* fix issues with undelegatio end time (#175)

* Fabo/fix undelegationendtime (#177)

* fix issues with undelegatio end time

* catch undelegation attribute not found

* Fabo/fix undelegationendtime for regen (#178)

* fix issues with undelegatio end time

* catch undelegation attribute not found

* fix regen transaction reducers

* Display Deposit Period End Date correctly for proposals in deposit period (#181)

* Return proposal.voting_end_time in deposit period

* Return deposit_end_time instead

* update to new reducers and chain-id (#182)

* fix rewards not being extracted correctly

* linted

* trigger deploy

* Ana/105 livepeer into production (#114)

* add livepeer first files

* first tentative. add transcoder type and queries

* progress

* progress + trying

* eslint fix

* working

* recover missing config enabletestnet

* delete livepeer from resolver and schema

* try getallvalidators in livepeerv0-source

* todos: own subscription and own reducers

* eslint fix

* refactored into graphql data source

* add livepeer to networks json

* little hack (temporary)

* fix silly eslint error

* start playing

* fetch works. add to apollo

* fix lint

* get last round id/height

* fix lint

* set all feature flags to false

* forward. add livepeer reducer. 400 bad request

* fix lint

* kind of working

* fix networkId

* colin/ make node subscription great

* use transcoders no orchestrators. getValidator

* connecting to block height and validators display

* minor lint

* add validator name

* provisory getselfstake

* improve validator reducer

* use bignumber lib. add getdelegatorsstake

* fix lint

* fix gettotal stake delegators

* fix lint

* clean up

* get self stake

* delete livepeer-queries

* handle url with node url class

* delete extra back ticks

* invisible lint fix

* better prevent than regret

* delete getlastrounid function

* fix total stake and self stake

* remove console log

* use getblockheight to find last block

* get validators from db

* get more names

* get ALL validators

* use validator query string

* use bignumber instead of parseint

* minor lint

* fix validators names

* improve condition

* get all validators for real

* fix search filter for operator address

* fix search filter

* finishing fixes (formatbech32 and bignumber)

* try implementing votingpower. no api support

* refactoring and renaming

* enable votingpower

* livepeer is mainnet

* fix voting power filter (#188)

* disable livepeer for now (#191)

* double the gas estimate for txs (#193)

* wait for txs to be included in a block (#194)

* Move expected returns to separate resolver (#172)

* Move expected returns to separate resolver

* Scale result by 1/1000000

* increase gas again (#200)

* Fabo/track failing txs (#201)

* track failing txs

* remove dead code

* linted

* trigger CI

* Fabo/track failing txs (#202)

* track failing txs

* remove dead code

* linted

* track failures in broadcasting

* better error

* Fabo/sync again (#204)

* switch back to sync mode

* use transactions in block for events

* linted

* switch to own node (#205)

* fix getexpected returns for terra (#208)

* Aleksei/redis added (#214)

* redis added

* redis added

* WIP: Fabo/use redis pubsub (#209)

* use redis pubsub

* refactor

* Fix redis import

* validator picture fixed (#217)

* Revert "validator picture fixed (#217)" (#218)

This reverts commit f9250db.

* Revert "Revert "validator picture fixed (#217)" (#218)" (#219)

This reverts commit c785b0f.

* Fabo/refactor enrich validator (#220)

* refactor enriche validator

* use validator info for name

* Fabo+Jordan/livepeer improvements (#210)

* add livepeer first files

* first tentative. add transcoder type and queries

* progress

* progress + trying

* eslint fix

* working

* recover missing config enabletestnet

* delete livepeer from resolver and schema

* try getallvalidators in livepeerv0-source

* todos: own subscription and own reducers

* eslint fix

* refactored into graphql data source

* add livepeer to networks json

* little hack (temporary)

* fix silly eslint error

* start playing

* fetch works. add to apollo

* fix lint

* get last round id/height

* fix lint

* set all feature flags to false

* forward. add livepeer reducer. 400 bad request

* fix lint

* kind of working

* fix networkId

* colin/ make node subscription great

* use transcoders no orchestrators. getValidator

* connecting to block height and validators display

* minor lint

* add validator name

* provisory getselfstake

* improve validator reducer

* use bignumber lib. add getdelegatorsstake

* fix lint

* fix gettotal stake delegators

* fix lint

* clean up

* get self stake

* delete livepeer-queries

* handle url with node url class

* delete extra back ticks

* invisible lint fix

* better prevent than regret

* delete getlastrounid function

* fix total stake and self stake

* remove console log

* use getblockheight to find last block

* get validators from db

* get more names

* get ALL validators

* use validator query string

* use bignumber instead of parseint

* minor lint

* fix validators names

* improve condition

* get all validators for real

* fix search filter for operator address

* fix search filter

* finishing fixes (formatbech32 and bignumber)

* try implementing votingpower. no api support

* refactoring and renaming

* enable votingpower

* livepeer is mainnet

* fixed values to be correct

* comments

* cleanup

* refactored

* removed file

* fix getexpectedreturns

* fix validator name logic

* add todos

* lint

* Fabo/refactor enrich validator (#222)

* refactor enriche validator

* use validator info for name

* use same logic for single and multiple validator queries

* filter improper picutre values

* return picture from db

* fix asynchrony for enrichvalidator

* Fabo/async check for tx failure (#221)

* refactor

* Update lib/controller/transaction/index.js

Co-Authored-By: Jordan Bibla <[email protected]>

* fix subscription for failing txs

* fix polling

* bunch of fixes

* comments

* linted

* avoid double body read error

* linted
  • Loading branch information
faboweb authored Dec 18, 2019
1 parent 62e3878 commit b6c8c40
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 148 deletions.
72 changes: 70 additions & 2 deletions lib/controller/transaction/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const { getMessage } = require('./messageConstructor')
const { networks } = require('../../networks')
const Sentry = require('@sentry/node')
const { publishUserTransactionAdded } = require('../../subscriptions')
const reducers = require('../../reducers/cosmosV0-reducers') // TODO the whole transaction service only works for cosmos rn

global.fetch = require('node-fetch')

Expand Down Expand Up @@ -32,6 +34,8 @@ async function broadcast(tx) {
console.log(`Received broadcast: ${JSON.stringify(tx)}`)
try {
const hash = await broadcastTransaction(
tx.networkId,
tx.senderAddress,
networks[tx.networkId].api_url,
tx.signedMessage
)
Expand All @@ -40,7 +44,7 @@ async function broadcast(tx) {
success: true
}
} catch (e) {
Sentry.withScope(function(scope) {
Sentry.withScope(scope => {
scope.setExtra('api_url', networks[tx.networkId].api_url)
scope.setExtra('transaction', tx.signedMessage)
Sentry.captureException(e)
Expand All @@ -57,7 +61,7 @@ module.exports = {
broadcast
}

async function broadcastTransaction(url, signedTx) {
async function broadcastTransaction(networkId, senderAddress, url, signedTx) {
// broadcast transaction with signatures included
// `block` means we wait for the tx to be included into a block before returning. this helps with figuring out "out of gas" issues which only appear when the block is created
const body = createBroadcastBody(signedTx, `sync`)
Expand All @@ -80,6 +84,9 @@ async function broadcastTransaction(url, signedTx) {
.then(res => res.json())
.then(assertOk)

// check if tx is successful when executed vs when broadcasted
pollTransactionSuccess(networkId, senderAddress, url, res.txhash)

return res.txhash
}

Expand Down Expand Up @@ -114,3 +121,64 @@ function assertOk(res) {

return res
}

// TODO replace with a tx tracking system + respond to transactions included in a block and compare them against the ones done in Lunie
// as we broadcast transactions asynchronously we need to react to them failing once executed in a block
// the simplest way to do this in Cosmos is to poll for the tx until it either succeeds or fails
const MAX_POLL_ITERATIONS = 150 // 5mins
async function pollTransactionSuccess(
networkId,
senderAddress,
url,
hash,
iteration = 0
) {
let res
console.error('Polling tx ', hash)
try {
try {
res = await global.fetch(`${url}/txs/${hash}`).then(async res => {
if (res.status !== 200) {
throw new Error(await res.text())
} else {
return res.json()
}
})
} catch (error) {
// retry for 60s
if (iteration < MAX_POLL_ITERATIONS) {
await new Promise(resolve => setTimeout(resolve, 2000))
pollTransactionSuccess(
networkId,
senderAddress,
url,
hash,
iteration + 1
)
return
}

res = {
hash,
success: false,
height: null
}
throw new Error(
'Timed out waiting for the transaction to be included in a block'
)
}

assertOk(res)
} catch (error) {
console.error('TX failed:', hash, error)
const transaction = reducers.transactionReducer(res, reducers)
publishUserTransactionAdded(networkId, senderAddress, transaction)
Sentry.withScope(scope => {
scope.setExtra('api_url', url)
scope.setExtra('hash', hash)
scope.setExtra('address', senderAddress)
scope.setExtra('transaction', res)
Sentry.captureException(error)
})
}
}
3 changes: 2 additions & 1 deletion lib/cosmos-node-subscription.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class CosmosNodeSubscription {
this.store.update({ height, block, validators: validatorMap })
publishBlockAdded(this.network.id, block)
// TODO remove, only for demo purposes
publishEvent(this.network.id, 'block', '', block)
// publishEvent(this.network.id, 'block', '', block)

// in the case of height being undefined to query for latest
// eslint-disable-next-line require-atomic-updates
Expand All @@ -58,6 +58,7 @@ class CosmosNodeSubscription {
// For each transaction listed in a block we extract the relevant addresses. This is published to the network.
// A GraphQL resolver is listening for these messages and sends the
// transaction to each subscribed user.
// TODO doesn't handle failing txs as it doesn't extract addresses from those txs (they are not tagged)
block.transactions.forEach(tx => {
let addresses = []
try {
Expand Down
87 changes: 25 additions & 62 deletions lib/livepeerV0-source.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const { GraphQLDataSource } = require('./helpers/GraphQLDataSource')
const BigNumber = require('bignumber.js')
const _ = require('lodash')

const LPT_CONVERSION = `1000000000000000000`

class LivepeerV0API extends GraphQLDataSource {
constructor(network) {
Expand All @@ -12,20 +13,8 @@ class LivepeerV0API extends GraphQLDataSource {
id
active
status
lastRewardRound {
id
}
rewardCut
feeShare
pricePerSegment
pendingRewardCut
pendingFeeShare
pendingPricePerSegment
totalStake
delegators {
id
bondedAmount
}
`
}

Expand All @@ -48,12 +37,7 @@ class LivepeerV0API extends GraphQLDataSource {
`
rounds(where: { id: ${blockHeight} }) {
id
initialized
length
timestamp
lastInitializedRound
startBlock
mintableTokens
}
`
)
Expand All @@ -77,7 +61,7 @@ class LivepeerV0API extends GraphQLDataSource {
async getValidators(active) {
const { transcoders } = await this.query(
`
transcoders(where: {active: ${active}, status_not: null}) {
transcoders(where:{active:${active ? 'true' : 'false'}}) {
${this.validatorQueryString}
}
`
Expand All @@ -86,52 +70,19 @@ class LivepeerV0API extends GraphQLDataSource {
}

async getTotalStakedTokens(transcoders) {
let totalStakedTokens = 0
transcoders.forEach(validator => {
totalStakedTokens = BigNumber(totalStakedTokens)
.plus(BigNumber(validator.totalStake))
.plus(BigNumber(validator.totalDelegatorsStake))
})
return totalStakedTokens.div('10000000000000000')
}

async getDelegatorsStake(validator) {
let totalDelegatorsStake = 0
validator.delegators.forEach(delegator => {
totalDelegatorsStake = BigNumber(totalDelegatorsStake).plus(
BigNumber(delegator.bondedAmount)
)
})
validator = {
...validator,
totalDelegatorsStake: totalDelegatorsStake.toString()
}
return validator
}

async getValidator(id) {
const { transcoder } = await this.query(
`
transcoders(where: { id: ${id} }) {
${this.validatorQueryString}
}
`
)
return this.reducers.validatorReducer(transcoder)
const totalStakedTokens = transcoders.reduce((sum, validator) => {
return BigNumber(sum).plus(BigNumber(validator.totalStake))
}, BigNumber(0))
// LPT is represented by 1:1000000000000000000 internally
return totalStakedTokens.div(LPT_CONVERSION)
}

async getAllValidators() {
// Until they fix their API we need to query separately for active and inactive validators
const inactiveTranscoders = await this.getValidators(false)
const activeTranscoders = await this.getValidators(true)
const transcoders = _.union(inactiveTranscoders, activeTranscoders)
const modTranscoders = await Promise.all(
transcoders.map(
async validator => await this.getDelegatorsStake(validator)
)
)
const totalStakedTokens = await this.getTotalStakedTokens(modTranscoders)
return modTranscoders.map(validator =>
const totalStakedTokens = await this.getTotalStakedTokens(activeTranscoders)
const transcoders = inactiveTranscoders.concat(activeTranscoders)
return transcoders.map(validator =>
this.reducers.validatorReducer(
this.networkId,
validator,
Expand All @@ -140,9 +91,21 @@ class LivepeerV0API extends GraphQLDataSource {
)
}

async getSelfStake(validator) {
return validator.selfStake
async getSelfStake() {
return undefined
}

getExpectedReturns(validator) {
return this.reducers.livepeerExpectedRewardsReducer({
rewardCut: validator.rewardCut,
// assuming following fixed values which is not true and needs to be queried via the future protocol query
inflation: 1172, // TODO change to API call
inflationChange: 3, // TODO change to API call
totalSupply: '17919760877408440511808797', // TODO change to API call
totalStaked: '11426550355221975909835117' // TODO change to API call
})
}
}

module.exports = LivepeerV0API
module.exports.LPT_CONVERSION = LPT_CONVERSION
95 changes: 66 additions & 29 deletions lib/reducers/livepeerV0-reducers.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const BigNumber = require('bignumber.js')
const { LPT_CONVERSION } = require('../livepeerV0-source')

function blockReducer(networkId, block) {
return {
Expand All @@ -11,23 +12,16 @@ function blockReducer(networkId, block) {
}

function validatorCommissionReducer(commission) {
return commission
? BigNumber(commission)
.div('1000000')
.toString()
: null
// precision of commision is 1:1000000
return BigNumber(commission).div('1000000')
}

function validatorStatusEnumReducer(active) {
return active ? 'ACTIVE' : 'INACTIVE'
}

function bigNumberReducer(bignumber) {
return bignumber
? BigNumber(bignumber)
.div('1000000000000000000')
.toString()
: null
return bignumber ? BigNumber(bignumber).div(LPT_CONVERSION) : null
}

function formatBech32Reducer(address) {
Expand All @@ -36,39 +30,82 @@ function formatBech32Reducer(address) {
}
}

function totalStakeReducer(validator) {
return BigNumber(validator.totalStake)
.plus(BigNumber(validator.totalDelegatorsStake))
.div('1000000000000000000')
.toString()
}

function votingPowerReducer(validator, totalStakedTokens) {
const totalValidatorStake = BigNumber(validator.totalStake).plus(
BigNumber(validator.totalDelegatorsStake)
return BigNumber(bigNumberReducer(validator.totalStake)).div(
totalStakedTokens
)
return totalValidatorStake
.div('10000000000000000')
.div(totalStakedTokens)
.toString()
}

function livepeerExpectedRewardsReducer({
rewardCut,
inflation,
inflationChange,
totalSupply,
totalStaked
}) {
return expectedRewardsPerToken({
rewardCut: validatorCommissionReducer(rewardCut).toNumber(),
inflation: validatorCommissionReducer(inflation).toNumber(),
inflationChange: validatorCommissionReducer(inflationChange).toNumber(),
totalSupply: bigNumberReducer(totalSupply).toNumber(),
totalStaked: bigNumberReducer(totalStaked).toNumber()
})
}

// extracted from the livepeer explorer
function expectedRewardsPerToken({
rewardCut,
inflation,
inflationChange,
totalSupply,
totalStaked
}) {
const principle = 1

let hoursPerYear = 8760
let averageHoursPerRound = 21
let roundsPerYear = hoursPerYear / averageHoursPerRound

let totalRewardTokens = 0
let roi = 0
let percentOfTotalStaked = principle / totalStaked
let participationRate = totalStaked / totalSupply
let totalRewardTokensMinusFee
let currentMintableTokens

for (let i = 0; i < roundsPerYear; i++) {
if (inflation < 0) break
currentMintableTokens = totalSupply * inflation
totalRewardTokens = percentOfTotalStaked * currentMintableTokens
totalRewardTokensMinusFee =
totalRewardTokens - totalRewardTokens * rewardCut
roi = roi + totalRewardTokensMinusFee
totalSupply = totalSupply + currentMintableTokens
inflation =
participationRate > 0.5
? inflation - inflationChange
: inflation + inflationChange
}
return roi
}

function validatorReducer(networkId, validator, totalStakedTokens) {
return {
networkId,
operatorAddress: validator.id,
tokens: totalStakeReducer(validator),
selfStake: bigNumberReducer(validator.totalStake),
tokens: bigNumberReducer(validator.totalStake),
selfStake: bigNumberReducer(validator.pendingStake), // TODO (when we have the new API up and running)
commission: validatorCommissionReducer(validator.rewardCut),
status: validatorStatusEnumReducer(validator.active),
statusDetailed: validator.status, // Registered/Unregistered
votingPower: votingPowerReducer(validator, totalStakedTokens),
expectedReturns: validatorCommissionReducer(validator.feeShare) // This percentage means how much from the reward the delegator is going to get (each round I presume)
statusDetailed: validator.status, // Registered/Unregistered,
rewardCut: validator.rewardCut,
votingPower: votingPowerReducer(validator, totalStakedTokens)
}
}

module.exports = {
validatorReducer,
blockReducer,
formatBech32Reducer
formatBech32Reducer,
livepeerExpectedRewardsReducer
}
Loading

0 comments on commit b6c8c40

Please sign in to comment.