diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index ef5296a30..834c86dab 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -161,7 +161,7 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso if len(genTx.Name) > 0 { desc := stake.NewDescription(genTx.Name, "", "", "") candidate := stake.NewCandidate(genTx.Address, genTx.PubKey, desc) - candidate.Assets = sdk.NewRat(freeFermionVal) + candidate.BondedShares = sdk.NewRat(freeFermionVal) stakeData.Candidates = append(stakeData.Candidates, candidate) // pool logic diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index b4529efd8..2d8b9d6a3 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -101,7 +101,7 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { assert.Equal(t, int64(7), barAcc.GetCoins().AmountOf("steak")) candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr)) assert.Equal(t, candidate.Address.String(), barAddr) - assert.Equal(t, int64(3), candidate.Assets.Evaluate()) + assert.Equal(t, int64(3), candidate.BondedShares.Evaluate()) // TODO timeout issues if not connected to the internet // unbond a single share @@ -117,7 +117,7 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) { //barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags)) //assert.Equal(t, int64(99998), barAcc.GetCoins().AmountOf("steak")) //candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr)) - //assert.Equal(t, int64(2), candidate.Assets.Evaluate()) + //assert.Equal(t, int64(2), candidate.BondedShares.Evaluate()) } func executeWrite(t *testing.T, cmdStr string, writes ...string) { diff --git a/types/rational.go b/types/rational.go index 7e0a09107..d89a5e655 100644 --- a/types/rational.go +++ b/types/rational.go @@ -168,3 +168,19 @@ func (r *Rat) UnmarshalAmino(text string) (err error) { r.Rat = *tempRat return nil } + +//___________________________________________________________________________________ + +// test if two rat arrays are the equal +func RatsEqual(r1s, r2s []Rat) bool { + if len(r1s) != len(r2s) { + return false + } + + for i, r1 := range r1s { + if !r1.Equal(r2s[i]) { + return false + } + } + return true +} diff --git a/types/rational_test.go b/types/rational_test.go index e59545bfc..30abb1a51 100644 --- a/types/rational_test.go +++ b/types/rational_test.go @@ -276,3 +276,24 @@ func TestEmbeddedStructSerializationGoWire(t *testing.T) { assert.Equal(t, obj.Field2, obj2.Field2) assert.True(t, obj.Field3.Equal(obj2.Field3), "original: %v, unmarshalled: %v", obj, obj2) } + +func TestRatsEqual(t *testing.T) { + tests := []struct { + r1s, r2s []Rat + eq bool + }{ + {[]Rat{NewRat(0)}, []Rat{NewRat(0)}, true}, + {[]Rat{NewRat(0)}, []Rat{NewRat(1)}, false}, + {[]Rat{NewRat(0)}, []Rat{}, false}, + {[]Rat{NewRat(0), NewRat(1)}, []Rat{NewRat(0), NewRat(1)}, true}, + {[]Rat{NewRat(1), NewRat(0)}, []Rat{NewRat(1), NewRat(0)}, true}, + {[]Rat{NewRat(1), NewRat(0)}, []Rat{NewRat(0), NewRat(1)}, false}, + {[]Rat{NewRat(1), NewRat(0)}, []Rat{NewRat(1)}, false}, + } + + for _, tc := range tests { + assert.Equal(t, tc.eq, RatsEqual(tc.r1s, tc.r2s)) + assert.Equal(t, tc.eq, RatsEqual(tc.r2s, tc.r1s)) + } + +} diff --git a/x/stake/fee_distribution.go b/x/stake/fee_distribution.go index 7da08dea1..22f2602e7 100644 --- a/x/stake/fee_distribution.go +++ b/x/stake/fee_distribution.go @@ -18,12 +18,15 @@ func (k Keeper) FeeHandler(ctx sdk.Context, collectedFees sdk.Coins) { candidate.ProposerRewardPool = candidate.ProposerRewardPool.Plus(toProposer) toReservePool := coinsMulRat(collectedFees, params.ReservePoolFee) - pool.ReservePool = pool.ReservePool.Plus(toReservePool) + pool.FeeReservePool = pool.FeeReservePool.Plus(toReservePool) distributedReward := (collectedFees.Minus(toProposer)).Minus(toReservePool) pool.FeePool = pool.FeePool.Plus(distributedReward) - pool.SumFeesReceived = pool.SumFeesReceived.Plus(distributedReward) - pool.RecentFee = distributedReward + pool.FeeSumReceived = pool.FeeSumReceived.Plus(distributedReward) + pool.FeeRecent = distributedReward + + // lastly update the FeeRecent term + pool.FeeRecent = collectedFees k.setPool(ctx, pool) } @@ -41,21 +44,26 @@ func coinsMulRat(coins sdk.Coins, rat sdk.Rat) sdk.Coins { //____________________________________________________________________________- // calculate adjustment changes for a candidate at a height -func CalculateAdjustmentChange(candidate Candidate, pool Pool, height int64) (candidate, pool) { +func CalculateAdjustmentChange(candidate Candidate, pool Pool, denoms []string, height int64) (Candidate, Pool) { heightRat := sdk.NewRat(height) lastHeightRat := sdk.NewRat(height - 1) - candidateFeeCount := candidate.VotingPower.Mul(heightRat) + candidateFeeCount := candidate.BondedShares.Mul(heightRat) poolFeeCount := pool.BondedShares.Mul(heightRat) - // calculate simple and projected pools - simplePool := candidateFeeCount.Quo(poolFeeCount).Mul(pool.SumFeesReceived) - calc1 := candidate.PrevPower.Mul(lastHeightRat).Div(pool.PrevPower.Mul(lastHeightRat)).Mul(pool.PrevFeesReceived) - calc2 := candidate.Power.Div(pool.Power).Mul(pool.RecentFee) - projectedPool := calc1 + calc2 + for i, denom := range denoms { + poolFeeSumReceived := sdk.NewRat(pool.FeeSumReceived.AmountOf(denom)) + poolFeeRecent := sdk.NewRat(pool.FeeRecent.AmountOf(denom)) + // calculate simple and projected pools + simplePool := candidateFeeCount.Quo(poolFeeCount).Mul(poolFeeSumReceived) + calc1 := candidate.PrevBondedShares.Mul(lastHeightRat).Quo(pool.PrevBondedShares.Mul(lastHeightRat)).Mul(poolFeeRecent) + calc2 := candidate.BondedShares.Quo(pool.BondedShares).Mul(poolFeeRecent) + projectedPool := calc1.Add(calc2) + + AdjustmentChange := simplePool.Sub(projectedPool) + candidate.FeeAdjustments[i] = candidate.FeeAdjustments[i].Add(AdjustmentChange) + pool.FeeAdjustments[i] = pool.FeeAdjustments[i].Add(AdjustmentChange) + } - AdjustmentChange := simplePool.Sub(projectedPool) - candidate.Adjustment += AdjustmentChange - pool.Adjustment += AdjustmentChange return candidate, pool } diff --git a/x/stake/handler.go b/x/stake/handler.go index 8d3bbb8b8..d82ab3dd1 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -285,7 +285,7 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { } // deduct shares from the candidate - if candidate.Liabilities.IsZero() { + if candidate.DelegatorShares.IsZero() { k.removeCandidate(ctx, candidate.Address) } else { k.setCandidate(ctx, candidate) diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index b4db952f0..796f40a07 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -46,8 +46,8 @@ func TestDuplicatesMsgDeclareCandidacy(t *testing.T) { assert.Equal(t, Unbonded, candidate.Status) assert.Equal(t, candidateAddr, candidate.Address) assert.Equal(t, pk, candidate.PubKey) - assert.Equal(t, sdk.NewRat(10), candidate.Assets) - assert.Equal(t, sdk.NewRat(10), candidate.Liabilities) + assert.Equal(t, sdk.NewRat(10), candidate.BondedShares) + assert.Equal(t, sdk.NewRat(10), candidate.DelegatorShares) assert.Equal(t, Description{}, candidate.Description) // one candidate cannot bond twice @@ -71,8 +71,8 @@ func TestIncrementsMsgDelegate(t *testing.T) { candidate, found := keeper.GetCandidate(ctx, candidateAddr) require.True(t, found) - assert.Equal(t, bondAmount, candidate.Liabilities.Evaluate()) - assert.Equal(t, bondAmount, candidate.Assets.Evaluate()) + assert.Equal(t, bondAmount, candidate.DelegatorShares.Evaluate()) + assert.Equal(t, bondAmount, candidate.BondedShares.Evaluate()) // just send the same msgbond multiple times msgDelegate := newTestMsgDelegate(delegatorAddr, candidateAddr, bondAmount) @@ -90,21 +90,21 @@ func TestIncrementsMsgDelegate(t *testing.T) { require.True(t, found) expBond := int64(i+1) * bondAmount - expLiabilities := int64(i+2) * bondAmount // (1 self delegation) + expDelegatorShares := int64(i+2) * bondAmount // (1 self delegation) expDelegatorAcc := initBond - expBond require.Equal(t, bond.Height, int64(i), "Incorrect bond height") gotBond := bond.Shares.Evaluate() - gotLiabilities := candidate.Liabilities.Evaluate() + gotDelegatorShares := candidate.DelegatorShares.Evaluate() gotDelegatorAcc := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom) require.Equal(t, expBond, gotBond, "i: %v\nexpBond: %v\ngotBond: %v\ncandidate: %v\nbond: %v\n", i, expBond, gotBond, candidate, bond) - require.Equal(t, expLiabilities, gotLiabilities, - "i: %v\nexpLiabilities: %v\ngotLiabilities: %v\ncandidate: %v\nbond: %v\n", - i, expLiabilities, gotLiabilities, candidate, bond) + require.Equal(t, expDelegatorShares, gotDelegatorShares, + "i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\ncandidate: %v\nbond: %v\n", + i, expDelegatorShares, gotDelegatorShares, candidate, bond) require.Equal(t, expDelegatorAcc, gotDelegatorAcc, "i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\ncandidate: %v\nbond: %v\n", i, expDelegatorAcc, gotDelegatorAcc, candidate, bond) @@ -129,8 +129,8 @@ func TestIncrementsMsgUnbond(t *testing.T) { candidate, found := keeper.GetCandidate(ctx, candidateAddr) require.True(t, found) - assert.Equal(t, initBond*2, candidate.Liabilities.Evaluate()) - assert.Equal(t, initBond*2, candidate.Assets.Evaluate()) + assert.Equal(t, initBond*2, candidate.DelegatorShares.Evaluate()) + assert.Equal(t, initBond*2, candidate.BondedShares.Evaluate()) // just send the same msgUnbond multiple times // TODO use decimals here @@ -148,19 +148,19 @@ func TestIncrementsMsgUnbond(t *testing.T) { require.True(t, found) expBond := initBond - int64(i+1)*unbondShares - expLiabilities := 2*initBond - int64(i+1)*unbondShares + expDelegatorShares := 2*initBond - int64(i+1)*unbondShares expDelegatorAcc := initBond - expBond gotBond := bond.Shares.Evaluate() - gotLiabilities := candidate.Liabilities.Evaluate() + gotDelegatorShares := candidate.DelegatorShares.Evaluate() gotDelegatorAcc := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom) require.Equal(t, expBond, gotBond, "i: %v\nexpBond: %v\ngotBond: %v\ncandidate: %v\nbond: %v\n", i, expBond, gotBond, candidate, bond) - require.Equal(t, expLiabilities, gotLiabilities, - "i: %v\nexpLiabilities: %v\ngotLiabilities: %v\ncandidate: %v\nbond: %v\n", - i, expLiabilities, gotLiabilities, candidate, bond) + require.Equal(t, expDelegatorShares, gotDelegatorShares, + "i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\ncandidate: %v\nbond: %v\n", + i, expDelegatorShares, gotDelegatorShares, candidate, bond) require.Equal(t, expDelegatorAcc, gotDelegatorAcc, "i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\ncandidate: %v\nbond: %v\n", i, expDelegatorAcc, gotDelegatorAcc, candidate, bond) @@ -217,7 +217,7 @@ func TestMultipleMsgDeclareCandidacy(t *testing.T) { balanceExpd := initBond - 10 balanceGot := accMapper.GetAccount(ctx, val.Address).GetCoins().AmountOf(params.BondDenom) require.Equal(t, i+1, len(candidates), "expected %d candidates got %d, candidates: %v", i+1, len(candidates), candidates) - require.Equal(t, 10, int(val.Liabilities.Evaluate()), "expected %d shares, got %d", 10, val.Liabilities) + require.Equal(t, 10, int(val.DelegatorShares.Evaluate()), "expected %d shares, got %d", 10, val.DelegatorShares) require.Equal(t, balanceExpd, balanceGot, "expected account to have %d, got %d", balanceExpd, balanceGot) } diff --git a/x/stake/keeper.go b/x/stake/keeper.go index 0eedd200d..c2645bfbe 100644 --- a/x/stake/keeper.go +++ b/x/stake/keeper.go @@ -105,7 +105,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { store.Set(GetCandidateKey(address), bz) // if the voting power is the same no need to update any of the other indexes - if oldFound && oldCandidate.Assets.Equal(candidate.Assets) { + if oldFound && oldCandidate.BondedShares.Equal(candidate.BondedShares) { return } @@ -117,7 +117,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { updateHeight = true } // else already in the validator set - retain the old validator height and counter - store.Delete(GetValidatorKey(address, oldCandidate.Assets, oldCandidate.ValidatorBondHeight, oldCandidate.ValidatorBondCounter, k.cdc)) + store.Delete(GetValidatorKey(address, oldCandidate.BondedShares, oldCandidate.ValidatorBondHeight, oldCandidate.ValidatorBondCounter, k.cdc)) } else { updateHeight = true } @@ -125,9 +125,9 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { if updateHeight { // wasn't a candidate or wasn't in the validator set, update the validator block height and counter candidate.ValidatorBondHeight = ctx.BlockHeight() - counter := k.getCounter(ctx) + counter := k.getIntraTxCounter(ctx) candidate.ValidatorBondCounter = counter - k.setCounter(ctx, counter+1) + k.setIntraTxCounter(ctx, counter+1) } // update the candidate record @@ -141,7 +141,7 @@ func (k Keeper) setCandidate(ctx sdk.Context, candidate Candidate) { // add to the validators to update list if is already a validator // or is a new validator - setAcc := false + //setAcc := false if store.Get(GetRecentValidatorKey(candidate.PubKey)) != nil { //setAcc = true @@ -174,7 +174,7 @@ func (k Keeper) removeCandidate(ctx sdk.Context, address sdk.Address) { // delete the old candidate record store := ctx.KVStore(k.storeKey) store.Delete(GetCandidateKey(address)) - store.Delete(GetValidatorKey(address, candidate.Assets, candidate.ValidatorBondHeight, candidate.ValidatorBondCounter, k.cdc)) + store.Delete(GetValidatorKey(address, candidate.BondedShares, candidate.ValidatorBondHeight, candidate.ValidatorBondCounter, k.cdc)) // delete from recent and power weighted validator groups if the validator // exists and add validator with zero power to the validator updates @@ -448,8 +448,6 @@ func (k Keeper) GetPowerChangesAfterHeight(ctx sdk.Context, earliestHeight int64 pcs = append(pcs, pc) } iterator.Close() - - k.cdc.MustUnmarshalBinary(b, ¶ms) return } diff --git a/x/stake/keeper_test.go b/x/stake/keeper_test.go index 16d04dd74..662f996b1 100644 --- a/x/stake/keeper_test.go +++ b/x/stake/keeper_test.go @@ -32,8 +32,8 @@ func TestCandidate(t *testing.T) { amts := []int64{9, 8, 7} for i, amt := range amts { candidates[i] = NewCandidate(addrVals[i], pks[i], Description{}) - candidates[i].Assets = sdk.NewRat(amt) - candidates[i].Liabilities = sdk.NewRat(amt) + candidates[i].BondedShares = sdk.NewRat(amt) + candidates[i].DelegatorShares = sdk.NewRat(amt) } // check the empty keeper first @@ -49,7 +49,7 @@ func TestCandidate(t *testing.T) { assert.True(t, candidates[0].equal(resCand), "%v \n %v", resCand, candidates[0]) // modify a records, save, and retrieve - candidates[0].Liabilities = sdk.NewRat(99) + candidates[0].DelegatorShares = sdk.NewRat(99) keeper.setCandidate(ctx, candidates[0]) resCand, found = keeper.GetCandidate(ctx, addrVals[0]) require.True(t, found) @@ -90,8 +90,8 @@ func TestBond(t *testing.T) { var candidates [3]Candidate for i, amt := range amts { candidates[i] = NewCandidate(addrVals[i], pks[i], Description{}) - candidates[i].Assets = sdk.NewRat(amt) - candidates[i].Liabilities = sdk.NewRat(amt) + candidates[i].BondedShares = sdk.NewRat(amt) + candidates[i].DelegatorShares = sdk.NewRat(amt) } // first add a candidates[0] to delegate too @@ -189,8 +189,8 @@ func TestGetValidators(t *testing.T) { var candidates [5]Candidate for i, amt := range amts { candidates[i] = NewCandidate(addrs[i], pks[i], Description{}) - candidates[i].Assets = sdk.NewRat(amt) - candidates[i].Liabilities = sdk.NewRat(amt) + candidates[i].BondedShares = sdk.NewRat(amt) + candidates[i].DelegatorShares = sdk.NewRat(amt) keeper.setCandidate(ctx, candidates[i]) } @@ -209,7 +209,7 @@ func TestGetValidators(t *testing.T) { assert.Equal(t, candidates[0].Address, validators[4].Address, "%v", validators) // test a basic increase in voting power - candidates[3].Assets = sdk.NewRat(500) + candidates[3].BondedShares = sdk.NewRat(500) keeper.setCandidate(ctx, candidates[3]) validators = keeper.GetValidators(ctx) require.Equal(t, len(validators), n) @@ -217,7 +217,7 @@ func TestGetValidators(t *testing.T) { assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators) // test a decrease in voting power - candidates[3].Assets = sdk.NewRat(300) + candidates[3].BondedShares = sdk.NewRat(300) keeper.setCandidate(ctx, candidates[3]) validators = keeper.GetValidators(ctx) require.Equal(t, len(validators), n) @@ -225,7 +225,7 @@ func TestGetValidators(t *testing.T) { assert.Equal(t, candidates[3].Address, validators[0].Address, "%v", validators) // test equal voting power, different age - candidates[3].Assets = sdk.NewRat(200) + candidates[3].BondedShares = sdk.NewRat(200) ctx = ctx.WithBlockHeight(10) keeper.setCandidate(ctx, candidates[3]) validators = keeper.GetValidators(ctx) @@ -246,8 +246,8 @@ func TestGetValidators(t *testing.T) { assert.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators) // change in voting power of both candidates, both still in v-set, no age change - candidates[3].Assets = sdk.NewRat(300) - candidates[4].Assets = sdk.NewRat(300) + candidates[3].BondedShares = sdk.NewRat(300) + candidates[4].BondedShares = sdk.NewRat(300) keeper.setCandidate(ctx, candidates[3]) validators = keeper.GetValidators(ctx) require.Equal(t, len(validators), n) @@ -262,7 +262,7 @@ func TestGetValidators(t *testing.T) { params := keeper.GetParams(ctx) params.MaxValidators = 2 keeper.setParams(ctx, params) - candidates[0].Assets = sdk.NewRat(500) + candidates[0].BondedShares = sdk.NewRat(500) keeper.setCandidate(ctx, candidates[0]) validators = keeper.GetValidators(ctx) require.Equal(t, uint16(len(validators)), params.MaxValidators) @@ -277,7 +277,7 @@ func TestGetValidators(t *testing.T) { ref https://github.com/cosmos/cosmos-sdk/issues/582#issuecomment-380757108 */ - candidates[4].Assets = sdk.NewRat(301) + candidates[4].BondedShares = sdk.NewRat(301) keeper.setCandidate(ctx, candidates[4]) validators = keeper.GetValidators(ctx) require.Equal(t, uint16(len(validators)), params.MaxValidators) @@ -285,14 +285,14 @@ func TestGetValidators(t *testing.T) { require.Equal(t, candidates[4].Address, validators[1].Address, "%v", validators) ctx = ctx.WithBlockHeight(40) // candidate 4 kicked out temporarily - candidates[4].Assets = sdk.NewRat(200) + candidates[4].BondedShares = sdk.NewRat(200) keeper.setCandidate(ctx, candidates[4]) validators = keeper.GetValidators(ctx) require.Equal(t, uint16(len(validators)), params.MaxValidators) require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators) require.Equal(t, candidates[3].Address, validators[1].Address, "%v", validators) // candidate 4 does not get spot back - candidates[4].Assets = sdk.NewRat(300) + candidates[4].BondedShares = sdk.NewRat(300) keeper.setCandidate(ctx, candidates[4]) validators = keeper.GetValidators(ctx) require.Equal(t, uint16(len(validators)), params.MaxValidators) @@ -308,18 +308,18 @@ func TestGetValidators(t *testing.T) { ref https://github.com/cosmos/cosmos-sdk/issues/582#issuecomment-381250392 */ - candidates[0].Assets = sdk.NewRat(2000) + candidates[0].BondedShares = sdk.NewRat(2000) keeper.setCandidate(ctx, candidates[0]) - candidates[1].Assets = sdk.NewRat(1000) - candidates[2].Assets = sdk.NewRat(1000) + candidates[1].BondedShares = sdk.NewRat(1000) + candidates[2].BondedShares = sdk.NewRat(1000) keeper.setCandidate(ctx, candidates[1]) keeper.setCandidate(ctx, candidates[2]) validators = keeper.GetValidators(ctx) require.Equal(t, uint16(len(validators)), params.MaxValidators) require.Equal(t, candidates[0].Address, validators[0].Address, "%v", validators) require.Equal(t, candidates[1].Address, validators[1].Address, "%v", validators) - candidates[1].Assets = sdk.NewRat(1100) - candidates[2].Assets = sdk.NewRat(1100) + candidates[1].BondedShares = sdk.NewRat(1100) + candidates[2].BondedShares = sdk.NewRat(1100) keeper.setCandidate(ctx, candidates[2]) keeper.setCandidate(ctx, candidates[1]) validators = keeper.GetValidators(ctx) @@ -330,11 +330,11 @@ func TestGetValidators(t *testing.T) { // reset assets / heights params.MaxValidators = 100 keeper.setParams(ctx, params) - candidates[0].Assets = sdk.NewRat(0) - candidates[1].Assets = sdk.NewRat(100) - candidates[2].Assets = sdk.NewRat(1) - candidates[3].Assets = sdk.NewRat(300) - candidates[4].Assets = sdk.NewRat(200) + candidates[0].BondedShares = sdk.NewRat(0) + candidates[1].BondedShares = sdk.NewRat(100) + candidates[2].BondedShares = sdk.NewRat(1) + candidates[3].BondedShares = sdk.NewRat(300) + candidates[4].BondedShares = sdk.NewRat(200) ctx = ctx.WithBlockHeight(0) keeper.setCandidate(ctx, candidates[0]) keeper.setCandidate(ctx, candidates[1]) @@ -343,7 +343,7 @@ func TestGetValidators(t *testing.T) { keeper.setCandidate(ctx, candidates[4]) // test a swap in voting power - candidates[0].Assets = sdk.NewRat(600) + candidates[0].BondedShares = sdk.NewRat(600) keeper.setCandidate(ctx, candidates[0]) validators = keeper.GetValidators(ctx) require.Equal(t, len(validators), n) @@ -373,8 +373,8 @@ func TestClearAccUpdateValidators(t *testing.T) { candidates := make([]Candidate, len(amts)) for i, amt := range amts { candidates[i] = NewCandidate(addrs[i], pks[i], Description{}) - candidates[i].Assets = sdk.NewRat(amt) - candidates[i].Liabilities = sdk.NewRat(amt) + candidates[i].BondedShares = sdk.NewRat(amt) + candidates[i].DelegatorShares = sdk.NewRat(amt) keeper.setCandidate(ctx, candidates[i]) } @@ -401,8 +401,8 @@ func TestGetAccUpdateValidators(t *testing.T) { var candidatesIn [5]Candidate for i, amt := range amts { candidatesIn[i] = NewCandidate(addrs[i], pks[i], Description{}) - candidatesIn[i].Assets = sdk.NewRat(amt) - candidatesIn[i].Liabilities = sdk.NewRat(amt) + candidatesIn[i].BondedShares = sdk.NewRat(amt) + candidatesIn[i].DelegatorShares = sdk.NewRat(amt) } // test from nothing to something @@ -447,12 +447,12 @@ func TestGetAccUpdateValidators(t *testing.T) { assert.Equal(t, 2, len(keeper.GetCandidates(ctx, 5))) assert.Equal(t, 0, len(keeper.getAccUpdateValidators(ctx))) - candidates[0].Assets = sdk.NewRat(600) + candidates[0].BondedShares = sdk.NewRat(600) keeper.setCandidate(ctx, candidates[0]) candidates = keeper.GetCandidates(ctx, 5) require.Equal(t, 2, len(candidates)) - assert.True(t, candidates[0].Assets.Equal(sdk.NewRat(600))) + assert.True(t, candidates[0].BondedShares.Equal(sdk.NewRat(600))) acc = keeper.getAccUpdateValidators(ctx) require.Equal(t, 1, len(acc)) assert.Equal(t, candidates[0].validator().abciValidator(keeper.cdc), acc[0]) @@ -464,8 +464,8 @@ func TestGetAccUpdateValidators(t *testing.T) { assert.Equal(t, 2, len(keeper.GetCandidates(ctx, 5))) assert.Equal(t, 0, len(keeper.getAccUpdateValidators(ctx))) - candidates[0].Assets = sdk.NewRat(200) - candidates[1].Assets = sdk.NewRat(100) + candidates[0].BondedShares = sdk.NewRat(200) + candidates[1].BondedShares = sdk.NewRat(100) keeper.setCandidate(ctx, candidates[0]) keeper.setCandidate(ctx, candidates[1]) @@ -528,7 +528,7 @@ func TestGetAccUpdateValidators(t *testing.T) { assert.Equal(t, 4, len(keeper.GetValidators(ctx))) assert.Equal(t, 0, len(keeper.getAccUpdateValidators(ctx))) - candidatesIn[4].Assets = sdk.NewRat(1) + candidatesIn[4].BondedShares = sdk.NewRat(1) keeper.setCandidate(ctx, candidatesIn[4]) assert.Equal(t, 5, len(keeper.GetCandidates(ctx, 5))) @@ -544,7 +544,7 @@ func TestGetAccUpdateValidators(t *testing.T) { assert.Equal(t, 4, len(keeper.GetValidators(ctx))) assert.Equal(t, 0, len(keeper.getAccUpdateValidators(ctx))) - candidatesIn[4].Assets = sdk.NewRat(1000) + candidatesIn[4].BondedShares = sdk.NewRat(1000) keeper.setCandidate(ctx, candidatesIn[4]) candidates = keeper.GetCandidates(ctx, 5) @@ -602,8 +602,8 @@ func TestIsRecentValidator(t *testing.T) { var candidatesIn [5]Candidate for i, amt := range amts { candidatesIn[i] = NewCandidate(addrVals[i], pks[i], Description{}) - candidatesIn[i].Assets = sdk.NewRat(amt) - candidatesIn[i].Liabilities = sdk.NewRat(amt) + candidatesIn[i].BondedShares = sdk.NewRat(amt) + candidatesIn[i].DelegatorShares = sdk.NewRat(amt) } // test that an empty validator set doesn't have any validators @@ -642,8 +642,8 @@ func TestGetTotalPrecommitVotingPower(t *testing.T) { var candidatesIn [5]Candidate for i, amt := range amts { candidatesIn[i] = NewCandidate(addrVals[i], pks[i], Description{}) - candidatesIn[i].Assets = sdk.NewRat(amt) - candidatesIn[i].Liabilities = sdk.NewRat(amt) + candidatesIn[i].BondedShares = sdk.NewRat(amt) + candidatesIn[i].DelegatorShares = sdk.NewRat(amt) keeper.setCandidate(ctx, candidatesIn[i]) } @@ -669,13 +669,13 @@ func TestParams(t *testing.T) { //check that the empty keeper loads the default resParams := keeper.GetParams(ctx) - assert.Equal(t, expParams, resParams) + assert.True(t, expParams.equal(resParams)) //modify a params, save, and retrieve expParams.MaxValidators = 777 keeper.setParams(ctx, expParams) resParams = keeper.GetParams(ctx) - assert.Equal(t, expParams, resParams) + assert.True(t, expParams.equal(resParams)) } func TestPool(t *testing.T) { @@ -684,13 +684,13 @@ func TestPool(t *testing.T) { //check that the empty keeper loads the default resPool := keeper.GetPool(ctx) - assert.Equal(t, expPool, resPool) + assert.True(t, expPool.equal(resPool)) //modify a params, save, and retrieve expPool.TotalSupply = 777 keeper.setPool(ctx, expPool) resPool = keeper.GetPool(ctx) - assert.Equal(t, expPool, resPool) + assert.True(t, expPool.equal(resPool)) } func TestValidatorsetKeeper(t *testing.T) { diff --git a/x/stake/pool.go b/x/stake/pool.go index f0c7bfae5..874312269 100644 --- a/x/stake/pool.go +++ b/x/stake/pool.go @@ -32,8 +32,8 @@ func (p Pool) unbondedShareExRate() sdk.Rat { func (p Pool) bondedToUnbondedPool(candidate Candidate) (Pool, Candidate) { // replace bonded shares with unbonded shares - p, tokens := p.removeSharesBonded(candidate.Assets) - p, candidate.Assets = p.addTokensUnbonded(tokens) + p, tokens := p.removeSharesBonded(candidate.BondedShares) + p, candidate.BondedShares = p.addTokensUnbonded(tokens) candidate.Status = Unbonded return p, candidate } @@ -42,8 +42,8 @@ func (p Pool) bondedToUnbondedPool(candidate Candidate) (Pool, Candidate) { func (p Pool) unbondedToBondedPool(candidate Candidate) (Pool, Candidate) { // replace unbonded shares with bonded shares - p, tokens := p.removeSharesUnbonded(candidate.Assets) - p, candidate.Assets = p.addTokensBonded(tokens) + p, tokens := p.removeSharesUnbonded(candidate.BondedShares) + p, candidate.BondedShares = p.addTokensBonded(tokens) candidate.Status = Bonded return p, candidate } @@ -92,10 +92,10 @@ func (p Pool) candidateAddTokens(candidate Candidate, } else { p, receivedGlobalShares = p.addTokensUnbonded(amount) } - candidate.Assets = candidate.Assets.Add(receivedGlobalShares) + candidate.BondedShares = candidate.BondedShares.Add(receivedGlobalShares) issuedDelegatorShares = exRate.Mul(receivedGlobalShares) - candidate.Liabilities = candidate.Liabilities.Add(issuedDelegatorShares) + candidate.DelegatorShares = candidate.DelegatorShares.Add(issuedDelegatorShares) return p, candidate, issuedDelegatorShares } @@ -112,7 +112,7 @@ func (p Pool) candidateRemoveShares(candidate Candidate, } else { p, createdCoins = p.removeSharesUnbonded(globalPoolSharesToRemove) } - candidate.Assets = candidate.Assets.Sub(globalPoolSharesToRemove) - candidate.Liabilities = candidate.Liabilities.Sub(shares) + candidate.BondedShares = candidate.BondedShares.Sub(globalPoolSharesToRemove) + candidate.DelegatorShares = candidate.DelegatorShares.Sub(shares) return p, candidate, createdCoins } diff --git a/x/stake/pool_test.go b/x/stake/pool_test.go index 6d70a85af..3a248d9e7 100644 --- a/x/stake/pool_test.go +++ b/x/stake/pool_test.go @@ -63,19 +63,19 @@ func TestBondedToUnbondedPool(t *testing.T) { Status: Bonded, Address: addrs[0], PubKey: pks[0], - Assets: sdk.OneRat(), - Liabilities: sdk.OneRat(), + BondedShares: sdk.OneRat(), + DelegatorShares: sdk.OneRat(), } poolB, candB := poolA.bondedToUnbondedPool(candA) // status unbonded assert.Equal(t, candB.Status, Unbonded) // same exchange rate, assets unchanged - assert.Equal(t, candB.Assets, candA.Assets) + assert.Equal(t, candB.BondedShares, candA.BondedShares) // bonded pool decreased - assert.Equal(t, poolB.BondedPool, poolA.BondedPool-candA.Assets.Evaluate()) + assert.Equal(t, poolB.BondedPool, poolA.BondedPool-candA.BondedShares.Evaluate()) // unbonded pool increased - assert.Equal(t, poolB.UnbondedPool, poolA.UnbondedPool+candA.Assets.Evaluate()) + assert.Equal(t, poolB.UnbondedPool, poolA.UnbondedPool+candA.BondedShares.Evaluate()) // conservation of tokens assert.Equal(t, poolB.UnbondedPool+poolB.BondedPool, poolA.BondedPool+poolA.UnbondedPool) } @@ -90,8 +90,8 @@ func TestUnbonbedtoBondedPool(t *testing.T) { Status: Bonded, Address: addrs[0], PubKey: pks[0], - Assets: sdk.OneRat(), - Liabilities: sdk.OneRat(), + BondedShares: sdk.OneRat(), + DelegatorShares: sdk.OneRat(), } candA.Status = Unbonded poolB, candB := poolA.unbondedToBondedPool(candA) @@ -99,11 +99,11 @@ func TestUnbonbedtoBondedPool(t *testing.T) { // status bonded assert.Equal(t, candB.Status, Bonded) // same exchange rate, assets unchanged - assert.Equal(t, candB.Assets, candA.Assets) + assert.Equal(t, candB.BondedShares, candA.BondedShares) // bonded pool increased - assert.Equal(t, poolB.BondedPool, poolA.BondedPool+candA.Assets.Evaluate()) + assert.Equal(t, poolB.BondedPool, poolA.BondedPool+candA.BondedShares.Evaluate()) // unbonded pool decreased - assert.Equal(t, poolB.UnbondedPool, poolA.UnbondedPool-candA.Assets.Evaluate()) + assert.Equal(t, poolB.UnbondedPool, poolA.UnbondedPool-candA.BondedShares.Evaluate()) // conservation of tokens assert.Equal(t, poolB.UnbondedPool+poolB.BondedPool, poolA.BondedPool+poolA.UnbondedPool) } @@ -180,11 +180,11 @@ func TestCandidateAddTokens(t *testing.T) { Status: Bonded, Address: addrs[0], PubKey: pks[0], - Assets: sdk.NewRat(9), - Liabilities: sdk.NewRat(9), + BondedShares: sdk.NewRat(9), + DelegatorShares: sdk.NewRat(9), } - poolA.BondedPool = candA.Assets.Evaluate() - poolA.BondedShares = candA.Assets + poolA.BondedPool = candA.BondedShares.Evaluate() + poolA.BondedShares = candA.BondedShares assert.Equal(t, candA.delegatorShareExRate(), sdk.OneRat()) assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat()) assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat()) @@ -193,7 +193,7 @@ func TestCandidateAddTokens(t *testing.T) { // shares were issued assert.Equal(t, sdk.NewRat(10).Mul(candA.delegatorShareExRate()), sharesB) // pool shares were added - assert.Equal(t, candB.Assets, candA.Assets.Add(sdk.NewRat(10))) + assert.Equal(t, candB.BondedShares, candA.BondedShares.Add(sdk.NewRat(10))) // conservation of tokens assert.Equal(t, poolB.BondedPool, 10+poolA.BondedPool) } @@ -206,11 +206,11 @@ func TestCandidateRemoveShares(t *testing.T) { Status: Bonded, Address: addrs[0], PubKey: pks[0], - Assets: sdk.NewRat(9), - Liabilities: sdk.NewRat(9), + BondedShares: sdk.NewRat(9), + DelegatorShares: sdk.NewRat(9), } - poolA.BondedPool = candA.Assets.Evaluate() - poolA.BondedShares = candA.Assets + poolA.BondedPool = candA.BondedShares.Evaluate() + poolA.BondedShares = candA.BondedShares assert.Equal(t, candA.delegatorShareExRate(), sdk.OneRat()) assert.Equal(t, poolA.bondedShareExRate(), sdk.OneRat()) assert.Equal(t, poolA.unbondedShareExRate(), sdk.OneRat()) @@ -219,7 +219,7 @@ func TestCandidateRemoveShares(t *testing.T) { // coins were created assert.Equal(t, coinsB, int64(10)) // pool shares were removed - assert.Equal(t, candB.Assets, candA.Assets.Sub(sdk.NewRat(10).Mul(candA.delegatorShareExRate()))) + assert.Equal(t, candB.BondedShares, candA.BondedShares.Sub(sdk.NewRat(10).Mul(candA.delegatorShareExRate()))) // conservation of tokens assert.Equal(t, poolB.UnbondedPool+poolB.BondedPool+coinsB, poolA.UnbondedPool+poolA.BondedPool) @@ -230,8 +230,8 @@ func TestCandidateRemoveShares(t *testing.T) { Status: Bonded, Address: addrs[0], PubKey: pks[0], - Assets: assets, - Liabilities: liabilities, + BondedShares: assets, + DelegatorShares: liabilities, } pool := Pool{ TotalSupply: 0, @@ -244,7 +244,7 @@ func TestCandidateRemoveShares(t *testing.T) { } shares := sdk.NewRat(29) msg := fmt.Sprintf("candidate %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)", - cand.Address, cand.Status, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) + cand.Address, cand.Status, cand.BondedShares, cand.DelegatorShares, cand.delegatorShareExRate()) msg = fmt.Sprintf("Removed %v shares from %s", shares, msg) newPool, _, tokens := pool.candidateRemoveShares(cand, shares) require.Equal(t, @@ -270,8 +270,8 @@ func randomCandidate(r *rand.Rand) Candidate { Status: status, Address: addrs[0], PubKey: pks[0], - Assets: assets, - Liabilities: liabilities, + BondedShares: assets, + DelegatorShares: liabilities, } } @@ -291,11 +291,11 @@ func randomSetup(r *rand.Rand, numCandidates int) (Pool, Candidates) { for i := 0; i < numCandidates; i++ { candidate := randomCandidate(r) if candidate.Status == Bonded { - pool.BondedShares = pool.BondedShares.Add(candidate.Assets) - pool.BondedPool += candidate.Assets.Evaluate() + pool.BondedShares = pool.BondedShares.Add(candidate.BondedShares) + pool.BondedPool += candidate.BondedShares.Evaluate() } else if candidate.Status == Unbonded { - pool.UnbondedShares = pool.UnbondedShares.Add(candidate.Assets) - pool.UnbondedPool += candidate.Assets.Evaluate() + pool.UnbondedShares = pool.UnbondedShares.Add(candidate.BondedShares) + pool.UnbondedPool += candidate.BondedShares.Evaluate() } candidates[i] = candidate } @@ -312,12 +312,12 @@ func OpBondOrUnbond(r *rand.Rand, p Pool, cand Candidate) (Pool, Candidate, int6 var msg string if cand.Status == Bonded { msg = fmt.Sprintf("Unbonded previously bonded candidate %s (assets: %v, liabilities: %v, delegatorShareExRate: %v)", - cand.Address, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) + cand.Address, cand.BondedShares, cand.DelegatorShares, cand.delegatorShareExRate()) p, cand = p.bondedToUnbondedPool(cand) } else if cand.Status == Unbonded { msg = fmt.Sprintf("Bonded previously unbonded candidate %s (assets: %v, liabilities: %v, delegatorShareExRate: %v)", - cand.Address, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) + cand.Address, cand.BondedShares, cand.DelegatorShares, cand.delegatorShareExRate()) p, cand = p.unbondedToBondedPool(cand) } return p, cand, 0, msg @@ -327,7 +327,7 @@ func OpBondOrUnbond(r *rand.Rand, p Pool, cand Candidate) (Pool, Candidate, int6 func OpAddTokens(r *rand.Rand, p Pool, cand Candidate) (Pool, Candidate, int64, string) { tokens := int64(r.Int31n(1000)) msg := fmt.Sprintf("candidate %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)", - cand.Address, cand.Status, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) + cand.Address, cand.Status, cand.BondedShares, cand.DelegatorShares, cand.delegatorShareExRate()) p, cand, _ = p.candidateAddTokens(cand, tokens) msg = fmt.Sprintf("Added %d tokens to %s", tokens, msg) return p, cand, -1 * tokens, msg // tokens are removed so for accounting must be negative @@ -338,13 +338,13 @@ func OpRemoveShares(r *rand.Rand, p Pool, cand Candidate) (Pool, Candidate, int6 var shares sdk.Rat for { shares = sdk.NewRat(int64(r.Int31n(1000))) - if shares.LT(cand.Liabilities) { + if shares.LT(cand.DelegatorShares) { break } } msg := fmt.Sprintf("Removed %v shares from candidate %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)", - shares, cand.Address, cand.Status, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) + shares, cand.Address, cand.Status, cand.BondedShares, cand.DelegatorShares, cand.delegatorShareExRate()) p, cand, tokens := p.candidateRemoveShares(cand, shares) return p, cand, tokens, msg @@ -409,21 +409,21 @@ func assertInvariants(t *testing.T, msg string, ) // nonnegative assets - require.False(t, cMod.Assets.LT(sdk.ZeroRat()), - "Applying operation \"%s\" resulted in negative candidate.Assets: %v (candidate.Liabilities: %v, candidate.delegatorShareExRate: %v, candidate.Address: %s)", + require.False(t, cMod.BondedShares.LT(sdk.ZeroRat()), + "Applying operation \"%s\" resulted in negative candidate.BondedShares: %v (candidate.DelegatorShares: %v, candidate.delegatorShareExRate: %v, candidate.Address: %s)", msg, - cMod.Assets, - cMod.Liabilities, + cMod.BondedShares, + cMod.DelegatorShares, cMod.delegatorShareExRate(), cMod.Address, ) // nonnegative liabilities - require.False(t, cMod.Liabilities.LT(sdk.ZeroRat()), - "Applying operation \"%s\" resulted in negative candidate.Liabilities: %v (candidate.Assets: %v, candidate.delegatorShareExRate: %v, candidate.Address: %s)", + require.False(t, cMod.DelegatorShares.LT(sdk.ZeroRat()), + "Applying operation \"%s\" resulted in negative candidate.DelegatorShares: %v (candidate.BondedShares: %v, candidate.delegatorShareExRate: %v, candidate.Address: %s)", msg, - cMod.Liabilities, - cMod.Assets, + cMod.DelegatorShares, + cMod.BondedShares, cMod.delegatorShareExRate(), cMod.Address, ) @@ -439,8 +439,8 @@ func TestPossibleOverflow(t *testing.T) { Status: Bonded, Address: addrs[0], PubKey: pks[0], - Assets: assets, - Liabilities: liabilities, + BondedShares: assets, + DelegatorShares: liabilities, } pool := Pool{ TotalSupply: 0, @@ -453,7 +453,7 @@ func TestPossibleOverflow(t *testing.T) { } tokens := int64(71) msg := fmt.Sprintf("candidate %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)", - cand.Address, cand.Status, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) + cand.Address, cand.Status, cand.BondedShares, cand.DelegatorShares, cand.delegatorShareExRate()) _, newCandidate, _ := pool.candidateAddTokens(cand, tokens) msg = fmt.Sprintf("Added %d tokens to %s", tokens, msg) diff --git a/x/stake/tick.go b/x/stake/tick.go index 2676ec595..994508b2a 100644 --- a/x/stake/tick.go +++ b/x/stake/tick.go @@ -35,6 +35,7 @@ func (k Keeper) Tick(ctx sdk.Context) (change []abci.Validator) { // XXX get the total validator of the previous validator set // XXX get the total validator of the current validator set + // XXX update pool PrevBondedShares // Calculate the PowerChange term return change diff --git a/x/stake/tick_test.go b/x/stake/tick_test.go index f75cf65b5..eeb67acec 100644 --- a/x/stake/tick_test.go +++ b/x/stake/tick_test.go @@ -72,8 +72,8 @@ func TestProcessProvisions(t *testing.T) { Status: Unbonded, PubKey: pks[i], Address: addrs[i], - Assets: sdk.NewRat(0), - Liabilities: sdk.NewRat(0), + BondedShares: sdk.NewRat(0), + DelegatorShares: sdk.NewRat(0), } if i < 5 { c.Status = Bonded diff --git a/x/stake/types.go b/x/stake/types.go index 5630387b0..7c0646e9b 100644 --- a/x/stake/types.go +++ b/x/stake/types.go @@ -17,6 +17,15 @@ type GenesisState struct { Bonds []DelegatorBond `json:"bonds"` } +func NewGenesisState(pool Pool, params Params, candidates []Candidate, bonds []DelegatorBond) GenesisState { + return GenesisState{ + Pool: pool, + Params: params, + Candidates: candidates, + Bonds: bonds, + } +} + // get raw genesis raw message for testing func DefaultGenesisState() GenesisState { return GenesisState{ @@ -37,7 +46,8 @@ type Params struct { MaxValidators uint16 `json:"max_validators"` // maximum number of validators BondDenom string `json:"bond_denom"` // bondable coin denomination - ReservePoolFee sdk.Rat `json:"reserve_pool_fee"` // percent of fees which go to reserve pool + FeeDenoms []string `json:"reserve_pool_fee"` // accepted fee denoms + ReservePoolFee sdk.Rat `json:"reserve_pool_fee"` // percent of fees which go to reserve pool } func (p Params) equal(p2 Params) bool { @@ -58,6 +68,7 @@ func defaultParams() Params { GoalBonded: sdk.NewRat(67, 100), MaxValidators: 100, BondDenom: "steak", + FeeDenoms: []string{"steak"}, ReservePoolFee: sdk.NewRat(5, 100), } } @@ -68,20 +79,23 @@ func defaultParams() Params { type Pool struct { TotalSupply int64 `json:"total_supply"` // total supply of all tokens BondedShares sdk.Rat `json:"bonded_shares"` // sum of all shares distributed for the Bonded Pool + UnbondingShares sdk.Rat `json:"unbonding_shares"` // shares moving from Bonded to Unbonded Pool UnbondedShares sdk.Rat `json:"unbonded_shares"` // sum of all shares distributed for the Unbonded Pool BondedPool int64 `json:"bonded_pool"` // reserve of bonded tokens + UnbondingPool int64 `json:"unbonded_pool"` // tokens moving from bonded to unbonded pool UnbondedPool int64 `json:"unbonded_pool"` // reserve of unbonded tokens held with candidates InflationLastTime int64 `json:"inflation_last_time"` // block which the last inflation was processed // TODO make time Inflation sdk.Rat `json:"inflation"` // current annual inflation rate DateLastCommissionReset int64 `json:"date_last_commission_reset"` // unix timestamp for last commission accounting reset (daily) - // XXX need to use special sdk.Rat amounts in coins here because added at small increments - ReservePool sdk.RatCoin `json:"reserve_pool"` // XXX reserve pool of collected fees for use by governance - FeePool sdk.RatCoin `json:"fee_pool"` // XXX fee pool for all the fee shares which have already been distributed - SumFeesReceived sdk.Coins `json:"sum_fees_received"` // XXX sum of all fees received, post reserve pool - RecentFee sdk.Coins `json:"recent_fee"` // XXX most recent fee collected - Adjustment sdk.Rat `json:"adjustment"` // XXX Adjustment factor for calculating global fee accum + // Fee Related + FeeReservePool sdk.Coins `json:"reserve_pool"` // XXX reserve pool of collected fees for use by governance + FeePool sdk.Coins `json:"fee_pool"` // XXX fee pool for all the fee shares which have already been distributed + FeeSumReceived sdk.Coins `json:"sum_fees_received"` // XXX sum of all fees received, post reserve pool + FeeRecent sdk.Coins `json:"recent_fee"` // XXX most recent fee collected + FeeAdjustments []sdk.Rat `json:"adjustment"` // XXX Adjustment factors for lazy fee accounting, couples with Params.BondDenoms + PrevBondedShares sdk.Rat `json:"adjustment"` // XXX last recorded bonded shares } func (p Pool) equal(p2 Pool) bool { @@ -93,11 +107,12 @@ func (p Pool) equal(p2 Pool) bool { p.InflationLastTime == p2.InflationLastTime && p.Inflation.Equal(p2.Inflation) && p.DateLastCommissionReset == p2.DateLastCommissionReset && - p.ReservePool.IsEqual(p2.ReservePool) && + p.FeeReservePool.IsEqual(p2.FeeReservePool) && p.FeePool.IsEqual(p2.FeePool) && - p.SumFeesReceived.IsEqual(p2.SumFeesReceived) && - p.RecentFee.IsEqual(p2.RecentFee) && - p.Adjustment.Equal(p2.Adjustment) + p.FeeSumReceived.IsEqual(p2.FeeSumReceived) && + p.FeeRecent.IsEqual(p2.FeeRecent) && + sdk.RatsEqual(p.FeeAdjustments, p2.FeeAdjustments) && + p.PrevBondedShares.Equal(p2.PrevBondedShares) } // initial pool for testing @@ -105,17 +120,20 @@ func initialPool() Pool { return Pool{ TotalSupply: 0, BondedShares: sdk.ZeroRat(), + UnbondingShares: sdk.ZeroRat(), UnbondedShares: sdk.ZeroRat(), BondedPool: 0, + UnbondingPool: 0, UnbondedPool: 0, InflationLastTime: 0, Inflation: sdk.NewRat(7, 100), DateLastCommissionReset: 0, - ReservePool: sdk.Coins(nil), + FeeReservePool: sdk.Coins(nil), FeePool: sdk.Coins(nil), - SumFeesReceived: sdk.Coins(nil), - RecentFee: sdk.Coins(nil), - Adjustment: sdk.ZeroRat(), + FeeSumReceived: sdk.Coins(nil), + FeeRecent: sdk.Coins(nil), + FeeAdjustments: []sdk.Rat{}, + PrevBondedShares: sdk.ZeroRat(), } } @@ -150,19 +168,27 @@ const ( // exchange rate. Voting power can be calculated as total bonds multiplied by // exchange rate. type Candidate struct { - Status CandidateStatus `json:"status"` // Bonded status - Address sdk.Address `json:"owner"` // Sender of BondTx - UnbondTx returns here - PubKey crypto.PubKey `json:"pub_key"` // Pubkey of candidate - Assets sdk.Rat `json:"assets"` // total shares of a global hold pools - Liabilities sdk.Rat `json:"liabilities"` // total shares issued to a candidate's delegators - Description Description `json:"description"` // Description terms for the candidate - ValidatorBondHeight int64 `json:"validator_bond_height"` // Earliest height as a bonded validator - ValidatorBondCounter int16 `json:"validator_bond_counter"` // Block-local tx index of validator change - ProposerRewardPool sdk.Coins `json:"proposer_reward_pool"` // XXX reward pool collected from being the proposer - Commission sdk.Rat `json:"commission"` // XXX the commission rate of fees charged to any delegators - CommissionMax sdk.Rat `json:"commission_max"` // XXX maximum commission rate which this candidate can ever charge - CommissionChangeRate sdk.Rat `json:"commission_change_rate"` // XXX maximum daily increase of the candidate commission - CommissionChangeToday sdk.Rat `json:"commission_change_today"` // XXX commission rate change today, reset each day (UTC time) + Status CandidateStatus `json:"status"` // Bonded status + Address sdk.Address `json:"owner"` // Sender of BondTx - UnbondTx returns here + PubKey crypto.PubKey `json:"pub_key"` // Pubkey of candidate + BondedShares sdk.Rat `json:"assets"` // total shares of a global hold pools + UnbondingShares sdk.Rat `json:"assets"` // total shares of a global hold pools + UnbondedShares sdk.Rat `json:"assets"` // total shares of a global hold pools + DelegatorShares sdk.Rat `json:"liabilities"` // total shares issued to a candidate's delegators + + Description Description `json:"description"` // Description terms for the candidate + ValidatorBondHeight int64 `json:"validator_bond_height"` // Earliest height as a bonded validator + ValidatorBondCounter int16 `json:"validator_bond_counter"` // Block-local tx index of validator change + ProposerRewardPool sdk.Coins `json:"proposer_reward_pool"` // XXX reward pool collected from being the proposer + + Commission sdk.Rat `json:"commission"` // XXX the commission rate of fees charged to any delegators + CommissionMax sdk.Rat `json:"commission_max"` // XXX maximum commission rate which this candidate can ever charge + CommissionChangeRate sdk.Rat `json:"commission_change_rate"` // XXX maximum daily increase of the candidate commission + CommissionChangeToday sdk.Rat `json:"commission_change_today"` // XXX commission rate change today, reset each day (UTC time) + + // fee related + FeeAdjustments []sdk.Rat `json:"adjustment"` // XXX Adjustment factors for lazy fee accounting, couples with Params.BondDenoms + PrevBondedShares sdk.Rat `json:"adjustment"` // total shares of a global hold pools } // Candidates - list of Candidates @@ -174,8 +200,8 @@ func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Descrip Status: Unbonded, Address: address, PubKey: pubKey, - Assets: sdk.ZeroRat(), - Liabilities: sdk.ZeroRat(), + BondedShares: sdk.ZeroRat(), + DelegatorShares: sdk.ZeroRat(), Description: description, ValidatorBondHeight: int64(0), ValidatorBondCounter: int16(0), @@ -184,6 +210,8 @@ func NewCandidate(address sdk.Address, pubKey crypto.PubKey, description Descrip CommissionMax: sdk.ZeroRat(), CommissionChangeRate: sdk.ZeroRat(), CommissionChangeToday: sdk.ZeroRat(), + FeeAdjustments: []sdk.Rat(nil), + PrevBondedShares: sdk.ZeroRat(), } } @@ -191,8 +219,8 @@ func (c Candidate) equal(c2 Candidate) bool { return c.Status == c2.Status && c.PubKey.Equals(c2.PubKey) && bytes.Equal(c.Address, c2.Address) && - c.Assets.Equal(c2.Assets) && - c.Liabilities.Equal(c2.Liabilities) && + c.BondedShares.Equal(c2.BondedShares) && + c.DelegatorShares.Equal(c2.DelegatorShares) && c.Description == c2.Description && c.ValidatorBondHeight == c2.ValidatorBondHeight && //c.ValidatorBondCounter == c2.ValidatorBondCounter && // counter is always changing @@ -200,7 +228,9 @@ func (c Candidate) equal(c2 Candidate) bool { c.Commission.Equal(c2.Commission) && c.CommissionMax.Equal(c2.CommissionMax) && c.CommissionChangeRate.Equal(c2.CommissionChangeRate) && - c.CommissionChangeToday.Equal(c2.CommissionChangeToday) + c.CommissionChangeToday.Equal(c2.CommissionChangeToday) && + sdk.RatsEqual(c.FeeAdjustments, c2.FeeAdjustments) && + c.PrevBondedShares.Equal(c2.PrevBondedShares) } // Description - description fields for a candidate @@ -222,10 +252,10 @@ func NewDescription(moniker, identity, website, details string) Description { // get the exchange rate of global pool shares over delegator shares func (c Candidate) delegatorShareExRate() sdk.Rat { - if c.Liabilities.IsZero() { + if c.DelegatorShares.IsZero() { return sdk.OneRat() } - return c.Assets.Quo(c.Liabilities) + return c.BondedShares.Quo(c.DelegatorShares) } // Validator returns a copy of the Candidate as a Validator. @@ -234,7 +264,7 @@ func (c Candidate) validator() Validator { return Validator{ Address: c.Address, PubKey: c.PubKey, - Power: c.Assets, + Power: c.BondedShares, Height: c.ValidatorBondHeight, Counter: c.ValidatorBondCounter, } diff --git a/x/stake/view_slash_keeper_test.go b/x/stake/view_slash_keeper_test.go index 7c75f5c95..e59c05852 100644 --- a/x/stake/view_slash_keeper_test.go +++ b/x/stake/view_slash_keeper_test.go @@ -20,8 +20,8 @@ func TestViewSlashBond(t *testing.T) { candidates[i] = Candidate{ Address: addrVals[i], PubKey: pks[i], - Assets: sdk.NewRat(amt), - Liabilities: sdk.NewRat(amt), + BondedShares: sdk.NewRat(amt), + DelegatorShares: sdk.NewRat(amt), } }