Home Reference Source

packages/oo7-substrate/src/srml/staking.js

  1. const { Bond, TransformBond } = require('oo7')
  2. const { ss58Encode } = require('../ss58')
  3. const { Balance } = require('../types')
  4. const balancesModule = require('./balances')
  5. const sessionModule = require('./session')
  6.  
  7. function compareAccountId(a, b) {
  8. return a.length === b.length && a.every((v, i) => b[i] === v)
  9. }
  10.  
  11. function accountIdMemberOf(member, set) {
  12. return set.find(item => compareAccountId(member, item)) !== undefined
  13. }
  14.  
  15. function augment (runtime, chain) {
  16. sessionModule.augment(runtime, chain)
  17. balancesModule.augment(runtime, chain)
  18. let session = runtime.session
  19. let staking = runtime.staking
  20. let balances = runtime.balances
  21. if (staking._extras) {
  22. return
  23. } else {
  24. staking._extras = true
  25. }
  26.  
  27. staking.thisSessionReward = new TransformBond(
  28. (r, l) => Math.round(r / l),
  29. [
  30. staking.sessionReward,
  31. session.lateness
  32. ]
  33. )
  34.  
  35. staking.currentNominatedBalance = who => staking.currentNominatorsFor(who)
  36. .map(ns => ns.map(n => balances.totalBalance(n)), 2)
  37. .map(bs => new Balance(bs.reduce((a, b) => a + b, 0)))
  38. staking.nominatedBalance = who => staking.nominatorsFor(who)
  39. .map(ns => ns.map(n => balances.totalBalance(n)), 2)
  40. .map(bs => new Balance(bs.reduce((a, b) => a + b, 0)))
  41. staking.stakingBalance = who => Bond
  42. .all([balances.totalBalance(who), staking.nominatedBalance(who)])
  43. .map(([f, r]) => new Balance(f + r));
  44. staking.currentStakingBalance = who => Bond
  45. .all([balances.totalBalance(who), staking.currentNominatedBalance(who)])
  46. .map(([f, r]) => new Balance(f + r));
  47. staking.eraLength = new TransformBond(
  48. (a, b) => a * b,
  49. [
  50. staking.sessionsPerEra,
  51. session.sessionLength
  52. ])
  53. staking.validators = Bond.all([staking.invulerables, session.validators])
  54. .map(([inv, v]) => v.map(who => ({
  55. who,
  56. ownBalance: balances.totalBalance(who),
  57. otherBalance: staking.currentNominatedBalance(who),
  58. nominators: staking.currentNominatorsFor(who),
  59. invulnerable: accountIdMemberOf(who, inv)
  60. })), 2)
  61. .map(v => v
  62. .map(i => Object.assign({balance: i.ownBalance.add(i.otherBalance)}, i))
  63. .sort((a, b) => b.balance - a.balance)
  64. )
  65.  
  66. staking.nextThreeUp = staking.intentions.map(
  67. l => ([session.validators, l.map(who => ({
  68. who, ownBalance: balances.totalBalance(who), otherBalance: staking.nominatedBalance(who)
  69. }) ) ]), 3
  70. ).map(([c, l]) => l
  71. .map(i => Object.assign({balance: i.ownBalance.add(i.otherBalance)}, i))
  72. .sort((a, b) => b.balance - a.balance)
  73. .filter(i => !c.some(x => x+'' == i.who+''))
  74. .slice(0, 3)
  75. )
  76.  
  77. staking.nextValidators = Bond
  78. .all([
  79. staking.intentions.map(v => v.map(who => ({
  80. who,
  81. ownBalance: balances.totalBalance(who),
  82. otherBalance: staking.nominatedBalance(who),
  83. nominators: staking.nominatorsFor(who)
  84. })), 2),
  85. staking.validatorCount
  86. ]).map(([as, vc]) => as
  87. .map(i => Object.assign({balance: i.ownBalance.add(i.otherBalance)}, i))
  88. .sort((a, b) => b.balance - a.balance)
  89. .slice(0, vc)
  90. )
  91.  
  92. staking.eraSessionsRemaining = new TransformBond(
  93. (spe, si, lec) => (spe - 1 - (si - lec) % spe),
  94. [
  95. staking.sessionsPerEra,
  96. session.currentIndex,
  97. staking.lastEraLengthChange
  98. ])
  99.  
  100. staking.eraBlocksRemaining = new TransformBond(
  101. (sl, sr, br) => br + sl * sr,
  102. [
  103. session.sessionLength,
  104. staking.eraSessionsRemaining,
  105. session.blocksRemaining
  106. ])
  107.  
  108. staking.intentionIndexOf = id =>
  109. new TransformBond((i, id) => {
  110. let ss58 = ss58Encode(id);
  111. return i.findIndex(a => ss58Encode(a) === ss58);
  112. }, [runtime.staking.intentions, id])
  113. staking.bondageOf = id =>
  114. new TransformBond(
  115. (b, h) => h >= b ? null : (b - h),
  116. [runtime.staking.bondage(id), chain.height]
  117. )
  118. staking.nominationIndex = (val) =>
  119. new TransformBond((i, id) => {
  120. let ss58 = ss58Encode(id);
  121. return i.findIndex(a => ss58Encode(a) === ss58);
  122. }, [runtime.staking.nominatorsFor(staking.nominating(val)), val])
  123. }
  124.  
  125. module.exports = { augment }