ctx with proposer, working through allocation test
This commit is contained in:
parent
22de85651f
commit
3b5e57be08
|
@ -188,6 +188,12 @@ func (c Context) WithBlockTime(newTime time.Time) Context {
|
|||
return c.WithBlockHeader(newHeader)
|
||||
}
|
||||
|
||||
func (c Context) WithProposer(addr ConsAddress) Context {
|
||||
newHeader := c.BlockHeader()
|
||||
newHeader.ProposerAddress = addr.Bytes()
|
||||
return c.WithBlockHeader(newHeader)
|
||||
}
|
||||
|
||||
func (c Context) WithBlockHeight(height int64) Context {
|
||||
return c.withValue(contextKeyBlockHeight, height)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package distribution
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
@ -12,8 +10,10 @@ import (
|
|||
// set the proposer for determining distribution during endblock
|
||||
func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper) {
|
||||
consAddr := sdk.ConsAddress(req.Header.ProposerAddress)
|
||||
fmt.Printf("debug consAddr: %v\n", consAddr)
|
||||
k.SetProposerConsAddr(ctx, consAddr)
|
||||
|
||||
// XXX TODO actually calculate this
|
||||
k.SetSumPrecommitPower(ctx, sdk.NewDec(1))
|
||||
}
|
||||
|
||||
// allocate fees
|
||||
|
|
|
@ -11,6 +11,12 @@ import (
|
|||
func (k Keeper) AllocateFees(ctx sdk.Context) {
|
||||
ctx.Logger().With("module", "x/distribution").Error(fmt.Sprintf("allocation height: %v", ctx.BlockHeight()))
|
||||
|
||||
// if there is no power in the system nothing should be allocated
|
||||
bondedTokens := k.stakeKeeper.TotalPower(ctx)
|
||||
if bondedTokens.IsZero() {
|
||||
return
|
||||
}
|
||||
|
||||
// get the proposer of this block
|
||||
proposerConsAddr := k.GetProposerConsAddr(ctx)
|
||||
proposerValidator := k.stakeKeeper.ValidatorByConsAddr(ctx, proposerConsAddr)
|
||||
|
@ -22,8 +28,7 @@ func (k Keeper) AllocateFees(ctx sdk.Context) {
|
|||
feesCollectedDec := types.NewDecCoins(feesCollected)
|
||||
|
||||
// allocated rewards to proposer
|
||||
bondedTokens := k.stakeKeeper.TotalPower(ctx)
|
||||
sumPowerPrecommitValidators := sdk.NewDec(1) // XXX TODO actually calculate this
|
||||
sumPowerPrecommitValidators := k.GetSumPrecommitPower(ctx)
|
||||
proposerMultiplier := sdk.NewDecWithPrec(1, 2).Add(sdk.NewDecWithPrec(4, 2).Mul(
|
||||
sumPowerPrecommitValidators).Quo(bondedTokens))
|
||||
proposerReward := feesCollectedDec.MulDec(proposerMultiplier)
|
||||
|
|
|
@ -1,7 +1,52 @@
|
|||
package keeper
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"testing"
|
||||
|
||||
func TestAllocateFees(t *testing.T) {
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAllocateFeesBasic(t *testing.T) {
|
||||
|
||||
// no community tax on inputs
|
||||
ctx, _, keeper, sk, fck := CreateTestInputAdvanced(t, false, 100, sdk.ZeroDec())
|
||||
stakeHandler := stake.NewHandler(sk)
|
||||
denom := sk.GetParams(ctx).BondDenom
|
||||
|
||||
//first make a validator
|
||||
msgCreateValidator := stake.NewTestMsgCreateValidator(valOpAddr1, valConsPk1, 10)
|
||||
got := stakeHandler(ctx, msgCreateValidator)
|
||||
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||
|
||||
// verify everything has been set in staking correctly
|
||||
validator, found := sk.GetValidator(ctx, valOpAddr1)
|
||||
require.True(t, found)
|
||||
require.Equal(t, sdk.Bonded, validator.Status)
|
||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens))
|
||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares))
|
||||
bondedTokens := sk.TotalPower(ctx)
|
||||
assert.True(sdk.DecEq(t, sdk.NewDec(10), bondedTokens))
|
||||
|
||||
// initial fee pool should be empty
|
||||
feePool := keeper.GetFeePool(ctx)
|
||||
require.Nil(t, feePool.Pool)
|
||||
|
||||
// allocate 10 denom of fees
|
||||
feeInputs := sdk.NewInt(100)
|
||||
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||
ctx = ctx.WithProposer(valConsAddr1)
|
||||
keeper.SetProposerConsAddr(ctx, valConsAddr1)
|
||||
keeper.SetSumPrecommitPower(ctx, sdk.NewDec(10))
|
||||
keeper.AllocateFees(ctx)
|
||||
|
||||
// verify that these fees have been received by the feePool
|
||||
feePool = keeper.GetFeePool(ctx)
|
||||
expRes := sdk.NewDecFromInt(feeInputs).Mul(sdk.NewDecWithPrec(95, 2)) // 5% goes to proposer
|
||||
require.Equal(t, 1, len(feePool.Pool))
|
||||
require.True(sdk.DecEq(t, expRes, feePool.Pool[0].Amount))
|
||||
}
|
||||
|
|
|
@ -3,29 +3,38 @@ package keeper
|
|||
import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestWithdrawDelegationReward(t *testing.T) {
|
||||
ctx, accMapper, keeper, sk := CreateTestInput(t, false, 100)
|
||||
ctx, accMapper, keeper, sk, fck := CreateTestInputDefault(t, false, 100)
|
||||
stakeHandler := stake.NewHandler(sk)
|
||||
denom := sk.GetParams(ctx).BondDenom
|
||||
|
||||
//first make a validator
|
||||
msgCreateValidator := stake.NewTestMsgCreateValidator(valAddr1, valPk1, 10)
|
||||
msgCreateValidator := stake.NewTestMsgCreateValidator(valOpAddr1, valConsPk1, 10)
|
||||
got := stakeHandler(ctx, msgCreateValidator)
|
||||
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||
_ = sk.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||
|
||||
// delegate
|
||||
msgDelegate := stake.NewTestMsgDelegate(delAddr1, valAddr1, 10)
|
||||
msgDelegate := stake.NewTestMsgDelegate(delAddr1, valOpAddr1, 10)
|
||||
got = stakeHandler(ctx, msgDelegate)
|
||||
require.True(t, got.IsOK())
|
||||
|
||||
amt := accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||
require.Equal(t, int64(90), amt.Int64())
|
||||
|
||||
keeper.WithdrawDelegationReward(ctx, delAddr1, valAddr1)
|
||||
feeInputs := sdk.NewInt(20)
|
||||
fck.SetCollectedFees(sdk.Coins{sdk.NewCoin(denom, feeInputs)})
|
||||
require.Equal(t, feeInputs, fck.GetCollectedFees(ctx).AmountOf(denom))
|
||||
|
||||
keeper.WithdrawDelegationReward(ctx, delAddr1, valOpAddr1)
|
||||
|
||||
amt = accMapper.GetAccount(ctx, delAddr1).GetCoins().AmountOf(denom)
|
||||
require.Equal(t, int64(100), amt.Int64())
|
||||
}
|
||||
|
||||
func TestWithdrawDelegationRewardsAll(t *testing.T) {
|
||||
|
|
|
@ -7,11 +7,6 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
)
|
||||
|
||||
// nolint
|
||||
const (
|
||||
ParamStoreKeyCommunityTax = "distr/community-tax"
|
||||
)
|
||||
|
||||
// keeper of the stake store
|
||||
type Keeper struct {
|
||||
storeKey sdk.StoreKey
|
||||
|
@ -70,7 +65,7 @@ func (k Keeper) GetProposerConsAddr(ctx sdk.Context) (consAddr sdk.ConsAddress)
|
|||
|
||||
b := tstore.Get(ProposerKey)
|
||||
if b == nil {
|
||||
panic("Stored fee pool should not have been nil")
|
||||
panic("Proposer cons address was likely not set in begin block")
|
||||
}
|
||||
|
||||
k.cdc.MustUnmarshalBinary(b, &consAddr)
|
||||
|
@ -86,7 +81,30 @@ func (k Keeper) SetProposerConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) {
|
|||
|
||||
//______________________________________________________________________
|
||||
|
||||
// Returns the current Deposit Procedure from the global param store
|
||||
// set the proposer public key for this block
|
||||
func (k Keeper) GetSumPrecommitPower(ctx sdk.Context) (sumPrecommitPower sdk.Dec) {
|
||||
tstore := ctx.KVStore(k.storeTKey)
|
||||
|
||||
b := tstore.Get(ProposerKey)
|
||||
if b == nil {
|
||||
panic("Proposer cons address was likely not set in begin block")
|
||||
}
|
||||
|
||||
k.cdc.MustUnmarshalBinary(b, &sumPrecommitPower)
|
||||
return
|
||||
}
|
||||
|
||||
// get the proposer public key for this block
|
||||
func (k Keeper) SetSumPrecommitPower(ctx sdk.Context, sumPrecommitPower sdk.Dec) {
|
||||
tstore := ctx.KVStore(k.storeTKey)
|
||||
b := k.cdc.MustMarshalBinary(sumPrecommitPower)
|
||||
tstore.Set(ProposerKey, b)
|
||||
}
|
||||
|
||||
//______________________________________________________________________
|
||||
// PARAM STORE
|
||||
|
||||
// Returns the current CommunityTax rate from the global param store
|
||||
// nolint: errcheck
|
||||
func (k Keeper) GetCommunityTax(ctx sdk.Context) sdk.Dec {
|
||||
var communityTax sdk.Dec
|
||||
|
|
|
@ -8,11 +8,17 @@ import (
|
|||
var (
|
||||
FeePoolKey = []byte{0x00} // key for global distribution state
|
||||
ValidatorDistInfoKey = []byte{0x01} // prefix for each key to a validator distribution
|
||||
DelegationDistInfoKey = []byte{0x02} // prefix for each key to a delegation distribution
|
||||
DelegationDistInfoKey = []byte{0x02} // prefix for each key to a delegation distribution
|
||||
DelegatorWithdrawInfoKey = []byte{0x03} // prefix for each key to a delegator withdraw info
|
||||
|
||||
// transient
|
||||
ProposerKey = []byte{0x00} // key for storing the proposer operator address
|
||||
ProposerKey = []byte{0x00} // key for storing the proposer operator address
|
||||
SumPrecommitPowerKey = []byte{0x01} // key for storing the power of the precommit validators
|
||||
)
|
||||
|
||||
// nolint
|
||||
const (
|
||||
ParamStoreKeyCommunityTax = "distr/community-tax"
|
||||
)
|
||||
|
||||
// gets the key for the validator distribution info from address
|
||||
|
|
|
@ -30,15 +30,22 @@ var (
|
|||
delAddr2 = sdk.AccAddress(delPk2.Address())
|
||||
delAddr3 = sdk.AccAddress(delPk3.Address())
|
||||
|
||||
valPk1 = ed25519.GenPrivKey().PubKey()
|
||||
valPk2 = ed25519.GenPrivKey().PubKey()
|
||||
valPk3 = ed25519.GenPrivKey().PubKey()
|
||||
valAddr1 = sdk.ValAddress(valPk1.Address())
|
||||
valAddr2 = sdk.ValAddress(valPk2.Address())
|
||||
valAddr3 = sdk.ValAddress(valPk3.Address())
|
||||
valAccAddr1 = sdk.AccAddress(valPk1.Address()) // generate acc addresses for these validator keys too
|
||||
valAccAddr2 = sdk.AccAddress(valPk2.Address())
|
||||
valAccAddr3 = sdk.AccAddress(valPk3.Address())
|
||||
valOpPk1 = ed25519.GenPrivKey().PubKey()
|
||||
valOpPk2 = ed25519.GenPrivKey().PubKey()
|
||||
valOpPk3 = ed25519.GenPrivKey().PubKey()
|
||||
valOpAddr1 = sdk.ValAddress(valOpPk1.Address())
|
||||
valOpAddr2 = sdk.ValAddress(valOpPk2.Address())
|
||||
valOpAddr3 = sdk.ValAddress(valOpPk3.Address())
|
||||
valAccAddr1 = sdk.AccAddress(valOpPk1.Address()) // generate acc addresses for these validator keys too
|
||||
valAccAddr2 = sdk.AccAddress(valOpPk2.Address())
|
||||
valAccAddr3 = sdk.AccAddress(valOpPk3.Address())
|
||||
|
||||
valConsPk1 = ed25519.GenPrivKey().PubKey()
|
||||
valConsPk2 = ed25519.GenPrivKey().PubKey()
|
||||
valConsPk3 = ed25519.GenPrivKey().PubKey()
|
||||
valConsAddr1 = sdk.ConsAddress(valConsPk1.Address())
|
||||
valConsAddr2 = sdk.ConsAddress(valConsPk2.Address())
|
||||
valConsAddr3 = sdk.ConsAddress(valConsPk3.Address())
|
||||
|
||||
addrs = []sdk.AccAddress{
|
||||
delAddr1, delAddr2, delAddr3,
|
||||
|
@ -63,9 +70,18 @@ func MakeTestCodec() *codec.Codec {
|
|||
return cdc
|
||||
}
|
||||
|
||||
// test input with default values
|
||||
func CreateTestInputDefault(t *testing.T, isCheckTx bool, initCoins int64) (
|
||||
sdk.Context, auth.AccountMapper, Keeper, stake.Keeper, DummyFeeCollectionKeeper) {
|
||||
|
||||
communityTax := sdk.NewDecWithPrec(2, 2)
|
||||
return CreateTestInputAdvanced(t, isCheckTx, initCoins, communityTax)
|
||||
}
|
||||
|
||||
// hogpodge of all sorts of input required for testing
|
||||
func CreateTestInput(t *testing.T, isCheckTx bool, initCoins int64) (
|
||||
sdk.Context, auth.AccountMapper, Keeper, stake.Keeper) {
|
||||
func CreateTestInputAdvanced(t *testing.T, isCheckTx bool, initCoins int64,
|
||||
communityTax sdk.Dec) (
|
||||
sdk.Context, auth.AccountMapper, Keeper, stake.Keeper, DummyFeeCollectionKeeper) {
|
||||
|
||||
keyDistr := sdk.NewKVStoreKey("distr")
|
||||
tkeyDistr := sdk.NewTransientStoreKey("transient_distr")
|
||||
|
@ -109,7 +125,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initCoins int64) (
|
|||
sk.SetPool(ctx, pool)
|
||||
}
|
||||
|
||||
fck := auth.NewFeeCollectionKeeper(cdc, keyFeeCollection)
|
||||
fck := DummyFeeCollectionKeeper{}
|
||||
pk := params.NewKeeper(cdc, keyParams)
|
||||
keeper := NewKeeper(cdc, keyDistr, tkeyDistr, pk.Setter(), ck, sk, fck, types.DefaultCodespace)
|
||||
|
||||
|
@ -118,7 +134,25 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initCoins int64) (
|
|||
|
||||
// set genesis items required for distribution
|
||||
keeper.SetFeePool(ctx, types.InitialFeePool())
|
||||
keeper.SetCommunityTax(ctx, sdk.NewDecWithPrec(2, 2))
|
||||
keeper.SetCommunityTax(ctx, communityTax)
|
||||
|
||||
return ctx, accountMapper, keeper, sk
|
||||
return ctx, accountMapper, keeper, sk, fck
|
||||
}
|
||||
|
||||
//__________________________________________________________________________________
|
||||
// fee collection keeper used only for testing
|
||||
type DummyFeeCollectionKeeper struct{}
|
||||
|
||||
var heldFees sdk.Coins
|
||||
var _ types.FeeCollectionKeeper = DummyFeeCollectionKeeper{}
|
||||
|
||||
// nolint
|
||||
func (fck DummyFeeCollectionKeeper) GetCollectedFees(_ sdk.Context) sdk.Coins {
|
||||
return heldFees
|
||||
}
|
||||
func (fck DummyFeeCollectionKeeper) SetCollectedFees(in sdk.Coins) {
|
||||
heldFees = in
|
||||
}
|
||||
func (fck DummyFeeCollectionKeeper) ClearCollectedFees(_ sdk.Context) {
|
||||
heldFees = sdk.Coins{}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue