From 25c1d8f33231c9537c87cd4bfdb44fdb9d8f2a47 Mon Sep 17 00:00:00 2001 From: Edgar Aroutiounian Date: Tue, 14 Apr 2020 08:10:05 -0700 Subject: [PATCH] [effective] Hold onto raw stake used per slot purchase as well (#2832) --- shard/committee/assignment.go | 15 +++++++------ staking/effective/calculate.go | 35 ++++++++++++++++------------- staking/effective/calculate_test.go | 14 ++++++------ 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/shard/committee/assignment.go b/shard/committee/assignment.go index 35a92ea9a..46ac0a3f2 100644 --- a/shard/committee/assignment.go +++ b/shard/committee/assignment.go @@ -4,8 +4,6 @@ import ( "encoding/json" "math/big" - "github.com/harmony-one/harmony/staking/availability" - "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/harmony/block" @@ -16,6 +14,7 @@ import ( "github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/shard" + "github.com/harmony-one/harmony/staking/availability" "github.com/harmony-one/harmony/staking/effective" staking "github.com/harmony-one/harmony/staking/types" "github.com/pkg/errors" @@ -325,11 +324,13 @@ func eposStakedCommittee( for i := range completedEPoSRound.AuctionWinners { purchasedSlot := completedEPoSRound.AuctionWinners[i] shardID := int(new(big.Int).Mod(purchasedSlot.Key.Big(), shardBig).Int64()) - shardState.Shards[shardID].Slots = append(shardState.Shards[shardID].Slots, shard.Slot{ - purchasedSlot.Addr, - purchasedSlot.Key, - &purchasedSlot.Stake, - }) + shardState.Shards[shardID].Slots = append( + shardState.Shards[shardID].Slots, shard.Slot{ + purchasedSlot.Addr, + purchasedSlot.Key, + &purchasedSlot.EPoSStake, + }, + ) } return shardState, nil diff --git a/staking/effective/calculate.go b/staking/effective/calculate.go index cf640ea9f..a39a30ff0 100644 --- a/staking/effective/calculate.go +++ b/staking/effective/calculate.go @@ -28,21 +28,24 @@ func effectiveStake(median, actual numeric.Dec) numeric.Dec { // SlotPurchase .. type SlotPurchase struct { - Addr common.Address `json:"slot-owner"` - Key shard.BLSPublicKey `json:"bls-public-key"` - Stake numeric.Dec `json:"eposed-stake"` + Addr common.Address + Key shard.BLSPublicKey + RawStake numeric.Dec + EPoSStake numeric.Dec } // MarshalJSON .. func (p SlotPurchase) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - Addr string `json:"slot-owner"` - Key string `json:"bls-public-key"` - Stake numeric.Dec `json:"eposed-stake"` + Addr string `json:"slot-owner"` + Key string `json:"bls-public-key"` + RawStake numeric.Dec `json:"raw-stake"` + EPoSStake numeric.Dec `json:"eposed-stake"` }{ common2.MustAddressToBech32(p.Addr), p.Key.Hex(), - p.Stake, + p.RawStake, + p.EPoSStake, }) } @@ -62,7 +65,7 @@ func Median(stakes []SlotPurchase) numeric.Dec { sort.SliceStable( stakes, func(i, j int) bool { - return stakes[i].Stake.GT(stakes[j].Stake) + return stakes[i].RawStake.GT(stakes[j].RawStake) }, ) const isEven = 0 @@ -70,9 +73,9 @@ func Median(stakes []SlotPurchase) numeric.Dec { case isEven: left := (l / 2) - 1 right := l / 2 - return stakes[left].Stake.Add(stakes[right].Stake).Quo(two) + return stakes[left].RawStake.Add(stakes[right].RawStake).Quo(two) default: - return stakes[l/2].Stake + return stakes[l/2].RawStake } } @@ -111,9 +114,11 @@ func Compute( QuoInt64(int64(slotsCount)) for i := 0; i < slotsCount; i++ { eposedSlots = append(eposedSlots, SlotPurchase{ - staker.addr, - staker.slot.SpreadAmong[i], - spread, + Addr: staker.addr, + Key: staker.slot.SpreadAmong[i], + // NOTE these are same because later the .EPoSStake mutated + RawStake: spread, + EPoSStake: spread, }) } } @@ -121,7 +126,7 @@ func Compute( sort.SliceStable( eposedSlots, 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) for i := range picks { - picks[i].Stake = effectiveStake(median, picks[i].Stake) + picks[i].EPoSStake = effectiveStake(median, picks[i].RawStake) } return median, picks diff --git a/staking/effective/calculate_test.go b/staking/effective/calculate_test.go index d0812fdfa..e8fefc370 100644 --- a/staking/effective/calculate_test.go +++ b/staking/effective/calculate_test.go @@ -62,7 +62,7 @@ func generateRandomSlots(num int) []SlotPurchase { key := shard.BLSPublicKey{} key.FromLibBLSPublicKey(secretKey.GetPublicKey()) 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 } @@ -71,15 +71,15 @@ func TestMedian(t *testing.T) { copyPurchases := append([]SlotPurchase{}, testingPurchases...) sort.SliceStable(copyPurchases, 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 if len(copyPurchases)%2 == 0 { - expectedMedian = copyPurchases[numPurchases-1].Stake.Add( - copyPurchases[numPurchases].Stake, + expectedMedian = copyPurchases[numPurchases-1].RawStake.Add( + copyPurchases[numPurchases].RawStake, ).Quo(two) } else { - expectedMedian = copyPurchases[numPurchases].Stake + expectedMedian = copyPurchases[numPurchases].RawStake } med := Median(testingPurchases) if !med.Equal(expectedMedian) { @@ -90,9 +90,9 @@ func TestMedian(t *testing.T) { func TestEffectiveStake(t *testing.T) { for _, val := range testingPurchases { 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)) - calculatedStake := effectiveStake(expectedMedian, val.Stake) + calculatedStake := effectiveStake(expectedMedian, val.RawStake) if !expectedStake.Equal(calculatedStake) { t.Errorf( "Expected: %s, Got: %s", expectedStake.String(), calculatedStake.String(),