You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
1.3 KiB
54 lines
1.3 KiB
package effective
|
|
|
|
import (
|
|
"fmt"
|
|
"math/big"
|
|
"sort"
|
|
|
|
"github.com/harmony-one/harmony/numeric"
|
|
)
|
|
|
|
// medium.com/harmony-one/introducing-harmonys-effective-proof-of-stake-epos-2d39b4b8d58
|
|
var (
|
|
c, _ = numeric.NewDecFromStr("0.15")
|
|
onePlusC = numeric.OneDec().Add(c)
|
|
oneMinusC = numeric.OneDec().Sub(c)
|
|
)
|
|
|
|
// Stake computes the effective proof of stake as descibed in whitepaper
|
|
func Stake(median, actual *big.Int) numeric.Dec {
|
|
medianDec := numeric.NewDecFromBigInt(median)
|
|
actualDec := numeric.NewDecFromBigInt(actual)
|
|
left := numeric.MinDec(onePlusC.Mul(medianDec), actualDec)
|
|
right := oneMinusC.Mul(medianDec)
|
|
return numeric.MaxDec(left, right)
|
|
}
|
|
|
|
// Median find the median stake
|
|
func Median(stakes []*big.Int) *big.Int {
|
|
sort.SliceStable(
|
|
stakes,
|
|
func(i, j int) bool { return stakes[i].Cmp(stakes[j]) <= 0 },
|
|
)
|
|
const isEven = 0
|
|
switch l := len(stakes); l % 2 {
|
|
case isEven:
|
|
middle := new(big.Int).Add(stakes[(l/2)-1], stakes[(l/2)+1])
|
|
return new(big.Int).Div(middle, big.NewInt(2))
|
|
default:
|
|
return stakes[l/2]
|
|
}
|
|
}
|
|
|
|
// Apply ..
|
|
func Apply(stakes []*big.Int) []numeric.Dec {
|
|
asNumeric := make([]numeric.Dec, len(stakes))
|
|
median := Median(stakes)
|
|
|
|
fmt.Println("Median is:", median.Uint64())
|
|
|
|
for i := range stakes {
|
|
asNumeric[i] = Stake(median, stakes[i])
|
|
}
|
|
return asNumeric
|
|
}
|
|
|