[effective] Hold onto raw stake used per slot purchase as well (#2832)

pull/2834/head
Edgar Aroutiounian 5 years ago committed by GitHub
parent eed00679cc
commit 25c1d8f332
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      shard/committee/assignment.go
  2. 35
      staking/effective/calculate.go
  3. 14
      staking/effective/calculate_test.go

@ -4,8 +4,6 @@ import (
"encoding/json" "encoding/json"
"math/big" "math/big"
"github.com/harmony-one/harmony/staking/availability"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
@ -16,6 +14,7 @@ import (
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/staking/availability"
"github.com/harmony-one/harmony/staking/effective" "github.com/harmony-one/harmony/staking/effective"
staking "github.com/harmony-one/harmony/staking/types" staking "github.com/harmony-one/harmony/staking/types"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -325,11 +324,13 @@ func eposStakedCommittee(
for i := range completedEPoSRound.AuctionWinners { for i := range completedEPoSRound.AuctionWinners {
purchasedSlot := completedEPoSRound.AuctionWinners[i] purchasedSlot := completedEPoSRound.AuctionWinners[i]
shardID := int(new(big.Int).Mod(purchasedSlot.Key.Big(), shardBig).Int64()) shardID := int(new(big.Int).Mod(purchasedSlot.Key.Big(), shardBig).Int64())
shardState.Shards[shardID].Slots = append(shardState.Shards[shardID].Slots, shard.Slot{ shardState.Shards[shardID].Slots = append(
purchasedSlot.Addr, shardState.Shards[shardID].Slots, shard.Slot{
purchasedSlot.Key, purchasedSlot.Addr,
&purchasedSlot.Stake, purchasedSlot.Key,
}) &purchasedSlot.EPoSStake,
},
)
} }
return shardState, nil return shardState, nil

@ -28,21 +28,24 @@ func effectiveStake(median, actual numeric.Dec) numeric.Dec {
// SlotPurchase .. // SlotPurchase ..
type SlotPurchase struct { type SlotPurchase struct {
Addr common.Address `json:"slot-owner"` Addr common.Address
Key shard.BLSPublicKey `json:"bls-public-key"` Key shard.BLSPublicKey
Stake numeric.Dec `json:"eposed-stake"` RawStake numeric.Dec
EPoSStake numeric.Dec
} }
// MarshalJSON .. // MarshalJSON ..
func (p SlotPurchase) MarshalJSON() ([]byte, error) { func (p SlotPurchase) MarshalJSON() ([]byte, error) {
return json.Marshal(struct { return json.Marshal(struct {
Addr string `json:"slot-owner"` Addr string `json:"slot-owner"`
Key string `json:"bls-public-key"` Key string `json:"bls-public-key"`
Stake numeric.Dec `json:"eposed-stake"` RawStake numeric.Dec `json:"raw-stake"`
EPoSStake numeric.Dec `json:"eposed-stake"`
}{ }{
common2.MustAddressToBech32(p.Addr), common2.MustAddressToBech32(p.Addr),
p.Key.Hex(), p.Key.Hex(),
p.Stake, p.RawStake,
p.EPoSStake,
}) })
} }
@ -62,7 +65,7 @@ func Median(stakes []SlotPurchase) numeric.Dec {
sort.SliceStable( sort.SliceStable(
stakes, stakes,
func(i, j int) bool { func(i, j int) bool {
return stakes[i].Stake.GT(stakes[j].Stake) return stakes[i].RawStake.GT(stakes[j].RawStake)
}, },
) )
const isEven = 0 const isEven = 0
@ -70,9 +73,9 @@ func Median(stakes []SlotPurchase) numeric.Dec {
case isEven: case isEven:
left := (l / 2) - 1 left := (l / 2) - 1
right := l / 2 right := l / 2
return stakes[left].Stake.Add(stakes[right].Stake).Quo(two) return stakes[left].RawStake.Add(stakes[right].RawStake).Quo(two)
default: default:
return stakes[l/2].Stake return stakes[l/2].RawStake
} }
} }
@ -111,9 +114,11 @@ func Compute(
QuoInt64(int64(slotsCount)) QuoInt64(int64(slotsCount))
for i := 0; i < slotsCount; i++ { for i := 0; i < slotsCount; i++ {
eposedSlots = append(eposedSlots, SlotPurchase{ eposedSlots = append(eposedSlots, SlotPurchase{
staker.addr, Addr: staker.addr,
staker.slot.SpreadAmong[i], Key: staker.slot.SpreadAmong[i],
spread, // NOTE these are same because later the .EPoSStake mutated
RawStake: spread,
EPoSStake: spread,
}) })
} }
} }
@ -121,7 +126,7 @@ func Compute(
sort.SliceStable( sort.SliceStable(
eposedSlots, eposedSlots,
func(i, j int) bool { func(i, j int) bool {
return eposedSlots[i].Stake.GT(eposedSlots[j].Stake) return eposedSlots[i].RawStake.GT(eposedSlots[j].RawStake)
}, },
) )
@ -144,7 +149,7 @@ func Apply(shortHand map[common.Address]*SlotOrder, pull int) (
) { ) {
median, picks := Compute(shortHand, pull) median, picks := Compute(shortHand, pull)
for i := range picks { for i := range picks {
picks[i].Stake = effectiveStake(median, picks[i].Stake) picks[i].EPoSStake = effectiveStake(median, picks[i].RawStake)
} }
return median, picks return median, picks

@ -62,7 +62,7 @@ func generateRandomSlots(num int) []SlotPurchase {
key := shard.BLSPublicKey{} key := shard.BLSPublicKey{}
key.FromLibBLSPublicKey(secretKey.GetPublicKey()) key.FromLibBLSPublicKey(secretKey.GetPublicKey())
stake := numeric.NewDecFromBigInt(big.NewInt(int64(stakeGen.Int63n(maxStakeGen)))) stake := numeric.NewDecFromBigInt(big.NewInt(int64(stakeGen.Int63n(maxStakeGen))))
randomSlots = append(randomSlots, SlotPurchase{addr, key, stake}) randomSlots = append(randomSlots, SlotPurchase{addr, key, stake, stake})
} }
return randomSlots return randomSlots
} }
@ -71,15 +71,15 @@ func TestMedian(t *testing.T) {
copyPurchases := append([]SlotPurchase{}, testingPurchases...) copyPurchases := append([]SlotPurchase{}, testingPurchases...)
sort.SliceStable(copyPurchases, sort.SliceStable(copyPurchases,
func(i, j int) bool { func(i, j int) bool {
return copyPurchases[i].Stake.LTE(copyPurchases[j].Stake) return copyPurchases[i].RawStake.LTE(copyPurchases[j].RawStake)
}) })
numPurchases := len(copyPurchases) / 2 numPurchases := len(copyPurchases) / 2
if len(copyPurchases)%2 == 0 { if len(copyPurchases)%2 == 0 {
expectedMedian = copyPurchases[numPurchases-1].Stake.Add( expectedMedian = copyPurchases[numPurchases-1].RawStake.Add(
copyPurchases[numPurchases].Stake, copyPurchases[numPurchases].RawStake,
).Quo(two) ).Quo(two)
} else { } else {
expectedMedian = copyPurchases[numPurchases].Stake expectedMedian = copyPurchases[numPurchases].RawStake
} }
med := Median(testingPurchases) med := Median(testingPurchases)
if !med.Equal(expectedMedian) { if !med.Equal(expectedMedian) {
@ -90,9 +90,9 @@ func TestMedian(t *testing.T) {
func TestEffectiveStake(t *testing.T) { func TestEffectiveStake(t *testing.T) {
for _, val := range testingPurchases { for _, val := range testingPurchases {
expectedStake := numeric.MaxDec( expectedStake := numeric.MaxDec(
numeric.MinDec(numeric.OneDec().Add(c).Mul(expectedMedian), val.Stake), numeric.MinDec(numeric.OneDec().Add(c).Mul(expectedMedian), val.RawStake),
numeric.OneDec().Sub(c).Mul(expectedMedian)) numeric.OneDec().Sub(c).Mul(expectedMedian))
calculatedStake := effectiveStake(expectedMedian, val.Stake) calculatedStake := effectiveStake(expectedMedian, val.RawStake)
if !expectedStake.Equal(calculatedStake) { if !expectedStake.Equal(calculatedStake) {
t.Errorf( t.Errorf(
"Expected: %s, Got: %s", expectedStake.String(), calculatedStake.String(), "Expected: %s, Got: %s", expectedStake.String(), calculatedStake.String(),

Loading…
Cancel
Save