fix: challangee rewards stay in dao module if challenge is not sucessful (#286)

* fix: challangee rewards stay in dao module if challenge is not sucessful

* refactor: split up coin conversion functions

* fix: add dao module coin conversion

* test: adjust test case for updated behavior

* chore: fix typo

* fix: do not mint claims for dao

* refactor: remove redundant statement

* fix: error handling on claim converstion fail

* fix: linter error

* chore: add comment to test case
---------

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>
This commit is contained in:
Lorenz Herzberger 2024-01-18 13:56:16 +01:00 committed by GitHub
parent cb230f1615
commit 8d0e189593
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 65 additions and 68 deletions

View File

@ -268,7 +268,7 @@ func (s *E2ETestSuite) TestPoPResult() {
challenges[i].Initiator = val.Address.String()
challenges[i].Challenger = aliceAddr.String()
challenges[i].Challengee = bobAddr.String()
challenges[i].Success = true
challenges[i].Success = blockHeight%2 == 0 // Need some successful and unsuccessful challenges for assertion of correct behavior
challenges[i].Finished = true
msg := daotypes.NewMsgReportPopResult(val.Address.String(), &challenges[i])
@ -287,7 +287,7 @@ func (s *E2ETestSuite) TestPoPResult() {
})
s.Require().NoError(err)
assert.Contains(s.T(), out.String(), conf.StagedDenom)
assert.Contains(s.T(), out.String(), "39954337890") // Total supply 5 * 7990867578 = 39954337890
assert.Equal(s.T(), "amount: \"21974885838\"\ndenom: stagedcrddl\n", out.String()) // Total supply 5 * 1997716894 + 2 * 5993150684 = 21974885838
out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, bank.GetBalancesCmd(), []string{
aliceAddr.String(),
@ -295,7 +295,7 @@ func (s *E2ETestSuite) TestPoPResult() {
})
s.Require().NoError(err)
assert.Contains(s.T(), out.String(), conf.StagedDenom)
assert.Contains(s.T(), out.String(), "9988584470") // 5 * 1997716894 = 9988584470
assert.Equal(s.T(), "amount: \"9988584470\"\ndenom: stagedcrddl\n", out.String()) // 5 * 1997716894 = 9988584470
out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, bank.GetBalancesCmd(), []string{
bobAddr.String(),
@ -303,7 +303,7 @@ func (s *E2ETestSuite) TestPoPResult() {
})
s.Require().NoError(err)
assert.Contains(s.T(), out.String(), conf.StagedDenom)
assert.Contains(s.T(), out.String(), "29965753420") // 5 * 5993150684 = 29965753420
assert.Equal(s.T(), "amount: \"11986301368\"\ndenom: stagedcrddl\n", out.String()) // 2 * 5993150684 = 11986301368
// send ReissuanceProposal
msg1 := daotypes.NewMsgReissueRDDLProposal(val.Address.String(), hex.EncodeToString(val.PubKey.Address()),
@ -345,23 +345,16 @@ func (s *E2ETestSuite) TestPoPResult() {
s.Require().NoError(err)
assert.Equal(s.T(), "[]", txResponse.RawLog)
// send DistributionResult
msg4 := daotypes.NewMsgDistributionResult(val.Address.String(), challenges[2].Height, "DaoTxID", "InvestorTxID", "PoPTxID")
output, err = e2etestutil.BuildSignBroadcastTx(s.T(), val.Address, msg4)
s.Require().NoError(err)
// send DistributionResult implicitly
s.Require().NoError(s.network.WaitForNextBlock())
txResponse, err = lib.GetTxResponseFromOut(output)
s.Require().NoError(err)
assert.Equal(s.T(), "[]", txResponse.RawLog)
// check balance for crddl
out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, bank.GetCmdQueryTotalSupply(), []string{
fmt.Sprintf("--%s=%s", bank.FlagDenom, conf.ClaimDenom),
})
s.Require().NoError(err)
assert.Contains(s.T(), out.String(), conf.ClaimDenom)
assert.Equal(s.T(), "amount: \"23972602734\"\ndenom: crddl\n", out.String()) // Total supply 3 * 5993150684 + 3 * 1997716894 = 23972602734
assert.Equal(s.T(), "amount: \"11986301366\"\ndenom: crddl\n", out.String()) // Total supply 1 * 5993150684 + 3 * 1997716894 = 11986301366
out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, bank.GetBalancesCmd(), []string{
aliceAddr.String(),
@ -377,5 +370,5 @@ func (s *E2ETestSuite) TestPoPResult() {
})
s.Require().NoError(err)
assert.Contains(s.T(), out.String(), conf.ClaimDenom)
assert.Equal(s.T(), "amount: \"17979452052\"\ndenom: crddl\n", out.String()) // 3 * 5993150684 = 17979452052
assert.Equal(s.T(), "amount: \"5993150684\"\ndenom: crddl\n", out.String()) // 1 * 5993150684 = 5993150684
}

View File

@ -4,6 +4,7 @@ import (
"context"
"strconv"
errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/planetmint/planetmint-go/config"
"github.com/planetmint/planetmint-go/util"
@ -21,9 +22,9 @@ func (k msgServer) DistributionResult(goCtx context.Context, msg *types.MsgDistr
err := k.resolveStagedClaims(ctx, distribution.FirstPop, distribution.LastPop)
if err != nil {
util.GetAppLogger().Error(ctx, "%s for provided PoP heights: %d %d", types.ErrResolvingStagedClaims.Error(), distribution.FirstPop, distribution.LastPop)
} else {
util.GetAppLogger().Info(ctx, "staged claims successfully for provided PoP heights: %d %d", distribution.FirstPop, distribution.LastPop)
return nil, errorsmod.Wrap(types.ErrConvertClaims, err.Error())
}
util.GetAppLogger().Info(ctx, "staged claims successfully for provided PoP heights: %d %d", distribution.FirstPop, distribution.LastPop)
k.StoreDistributionOrder(ctx, distribution)
} else {
util.GetAppLogger().Error(ctx, "%s for provided block height %s", types.ErrDistributionNotFound.Error(), strconv.FormatInt(msg.GetLastPop(), 10))
@ -42,10 +43,16 @@ func (k msgServer) resolveStagedClaims(ctx sdk.Context, start int64, end int64)
popParticipants := make(map[string]uint64)
for _, challenge := range challenges {
challengerAmt, challengeeAmt := getAmountsForChallenge(challenge)
// if challenge not finished nobody has claims
if !challenge.GetFinished() {
continue
}
_, challengerAmt, challengeeAmt := util.GetPopReward(challenge.Height)
popParticipants[challenge.Challenger] += challengerAmt
if challenge.GetSuccess() {
popParticipants[challenge.Challengee] += challengeeAmt
}
}
// second data structure because map iteration order is not guaranteed in GO
keys := make([]string, 0)
@ -53,7 +60,7 @@ func (k msgServer) resolveStagedClaims(ctx sdk.Context, start int64, end int64)
keys = append(keys, p)
}
for _, p := range keys {
err = k.convertClaim(ctx, p, popParticipants[p])
err = k.convertAccountClaim(ctx, p, popParticipants[p])
if err != nil {
return err
}
@ -63,7 +70,7 @@ func (k msgServer) resolveStagedClaims(ctx sdk.Context, start int64, end int64)
}
// convert per account
func (k msgServer) convertClaim(ctx sdk.Context, participant string, amount uint64) (err error) {
func (k msgServer) convertAccountClaim(ctx sdk.Context, participant string, amount uint64) (err error) {
conf := config.GetConfig()
accAddr, err := sdk.AccAddressFromBech32(participant)
if err != nil {
@ -73,21 +80,17 @@ func (k msgServer) convertClaim(ctx sdk.Context, participant string, amount uint
accStagedClaim := k.bankKeeper.GetBalance(ctx, accAddr, conf.StagedDenom)
if accStagedClaim.Amount.GTE(sdk.NewIntFromUint64(amount)) {
burnCoins := sdk.NewCoins(sdk.NewCoin(conf.StagedDenom, sdk.NewIntFromUint64(amount)))
mintCoins := sdk.NewCoins(sdk.NewCoin(conf.ClaimDenom, sdk.NewIntFromUint64(amount)))
burnCoins, mintCoins := getConvertCoins(amount)
err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, accAddr, types.ModuleName, burnCoins)
if err != nil {
return err
}
err = k.bankKeeper.BurnCoins(ctx, types.ModuleName, burnCoins)
if err != nil {
return err
}
err = k.bankKeeper.MintCoins(ctx, types.ModuleName, mintCoins)
err = k.convertCoins(ctx, burnCoins, mintCoins)
if err != nil {
return err
}
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, accAddr, mintCoins)
if err != nil {
return err
@ -97,11 +100,17 @@ func (k msgServer) convertClaim(ctx sdk.Context, participant string, amount uint
return
}
// gather amounts for accounts
func getAmountsForChallenge(challenge types.Challenge) (challenger uint64, challengee uint64) {
totalAmt, challengerAmt, challengeeAmt := util.GetPopReward(challenge.Height)
if challenge.Success {
return challengerAmt, challengeeAmt
func (k msgServer) convertCoins(ctx sdk.Context, burnCoins sdk.Coins, mintCoins sdk.Coins) (err error) {
err = k.bankKeeper.BurnCoins(ctx, types.ModuleName, burnCoins)
if err != nil {
return err
}
return totalAmt, 0
return k.bankKeeper.MintCoins(ctx, types.ModuleName, mintCoins)
}
func getConvertCoins(amount uint64) (burnCoins sdk.Coins, mintCoins sdk.Coins) {
conf := config.GetConfig()
burnCoins = sdk.NewCoins(sdk.NewCoin(conf.StagedDenom, sdk.NewIntFromUint64(amount)))
mintCoins = sdk.NewCoins(sdk.NewCoin(conf.ClaimDenom, sdk.NewIntFromUint64(amount)))
return
}

View File

@ -37,50 +37,44 @@ func (k msgServer) ReportPopResult(goCtx context.Context, msg *types.MsgReportPo
func (k msgServer) issuePoPRewards(ctx sdk.Context, challenge types.Challenge) (err error) {
conf := config.GetConfig()
total, _, _ := util.GetPopReward(challenge.Height)
total, challengerAmt, _ := util.GetPopReward(challenge.Height)
stagedCRDDL := sdk.NewCoin(conf.StagedDenom, sdk.ZeroInt())
if challenge.GetSuccess() {
stagedCRDDL = stagedCRDDL.AddAmount(sdk.NewIntFromUint64(total))
} else {
stagedCRDDL = stagedCRDDL.AddAmount(sdk.NewIntFromUint64(challengerAmt))
}
stagedCRDDL := sdk.NewCoin(conf.StagedDenom, sdk.NewIntFromUint64(total))
err = k.bankKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(stagedCRDDL))
if err != nil {
return err
return
}
if challenge.Success {
err = k.handlePoPSuccess(ctx, challenge)
if err != nil {
return err
}
} else {
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sdk.AccAddress(challenge.Challenger), sdk.NewCoins(stagedCRDDL))
if err != nil {
return err
}
}
return err
return k.handlePoP(ctx, challenge)
}
func (k msgServer) handlePoPSuccess(ctx sdk.Context, challenge types.Challenge) (err error) {
conf := config.GetConfig()
func (k msgServer) handlePoP(ctx sdk.Context, challenge types.Challenge) (err error) {
_, challengerAmt, challengeeAmt := util.GetPopReward(challenge.Height)
challengerCoin := sdk.NewCoin(conf.StagedDenom, sdk.NewIntFromUint64(challengerAmt))
challengeeCoin := sdk.NewCoin(conf.StagedDenom, sdk.NewIntFromUint64(challengeeAmt))
challengee, err := sdk.AccAddressFromBech32(challenge.Challengee)
err = k.sendRewards(ctx, challenge.GetChallenger(), challengerAmt)
if err != nil {
return err
}
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, challengee, sdk.NewCoins(challengeeCoin))
if err != nil {
return err
}
challenger, err := sdk.AccAddressFromBech32(challenge.Challenger)
if err != nil {
return err
}
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, challenger, sdk.NewCoins(challengerCoin))
if err != nil {
return err
}
return
}
if !challenge.GetSuccess() {
return
}
return k.sendRewards(ctx, challenge.GetChallengee(), challengeeAmt)
}
func (k msgServer) sendRewards(ctx sdk.Context, receiver string, amt uint64) (err error) {
conf := config.GetConfig()
coins := sdk.NewCoins(sdk.NewCoin(conf.StagedDenom, sdk.NewIntFromUint64(amt)))
receiverAddr, err := sdk.AccAddressFromBech32(receiver)
if err != nil {
return err
}
return k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, receiverAddr, coins)
}

View File

@ -26,4 +26,5 @@ var (
ErrReissuanceTxIDMissing = errorsmod.Register(ModuleName, 17, "reissuance has no transaction id")
ErrRestrictedMsg = errorsmod.Register(ModuleName, 18, "restricted validator msg")
ErrDistributionWrongHeight = errorsmod.Register(ModuleName, 19, "distribution wrong height")
ErrConvertClaims = errorsmod.Register(ModuleName, 20, "convert claim failed")
)