diff --git a/tests/e2e/dao/pop/selection_suite.go b/tests/e2e/dao/pop/selection_suite.go index 73e6050..aab89e6 100644 --- a/tests/e2e/dao/pop/selection_suite.go +++ b/tests/e2e/dao/pop/selection_suite.go @@ -211,7 +211,13 @@ func (s *SelectionE2ETestSuite) VerifyTokens(token string) { }) s.Require().NoError(err) assert.Contains(s.T(), out.String(), token) - assert.Equal(s.T(), "amount: \"18279472050\"\ndenom: "+token+"\n", out.String()) // Total supply 2 * 7990867578 (total supply) + 1 * 1997716894 (challenger) + 3 * 100000000 (validator) + 2 * 10000 (past unresolved claims) = 17979472050 + + // Account for 1 additional unfinished PoP when checking balances after distribution + if token == s.claimDenom { + assert.Equal(s.T(), "amount: \"18579472050\"\ndenom: "+token+"\n", out.String()) // Total supply 2 * 7990867578 (total supply) + 1 * 1997716894 (challenger) + 6 * 100000000 (validator) + 2 * 10000 (past unresolved claims) = 18579472050 + } else { + assert.Equal(s.T(), "amount: \"18479472050\"\ndenom: "+token+"\n", out.String()) // Total supply 2 * 7990867578 (total supply) + 1 * 1997716894 (challenger) + 5 * 100000000 (validator) + 2 * 10000 (past unresolved claims) = 18479472050 + } out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, bank.GetBalancesCmd(), []string{ machines[0].address, @@ -219,7 +225,7 @@ func (s *SelectionE2ETestSuite) VerifyTokens(token string) { }) s.Require().NoError(err) assert.Contains(s.T(), out.String(), token) - assert.Equal(s.T(), "amount: \"5993160682\"\ndenom: "+token+"\n", out.String()) // 3 * 1997716894 + 1 * 10000= 5993160682 + assert.Equal(s.T(), "amount: \"5993160682\"\ndenom: "+token+"\n", out.String()) // 3 * 1997716894 + 1 * 10000 = 5993160682 out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, bank.GetBalancesCmd(), []string{ machines[1].address, @@ -235,7 +241,13 @@ func (s *SelectionE2ETestSuite) VerifyTokens(token string) { }) s.Require().NoError(err) assert.Contains(s.T(), out.String(), token) - assert.Equal(s.T(), "amount: \"300000000\"\ndenom: "+token+"\n", out.String()) // 3 * 300000000 + + // Account for 1 additional unfinished PoP when checking balances after distribution + if token == s.claimDenom { + assert.Equal(s.T(), "amount: \"600000000\"\ndenom: "+token+"\n", out.String()) // 6 * 100000000 + } else { + assert.Equal(s.T(), "amount: \"500000000\"\ndenom: "+token+"\n", out.String()) // 5 * 100000000 + } } func (s *SelectionE2ETestSuite) TestTokenDistribution1() { diff --git a/x/dao/keeper/msg_server_distribution_result.go b/x/dao/keeper/msg_server_distribution_result.go index 872bb68..814a409 100644 --- a/x/dao/keeper/msg_server_distribution_result.go +++ b/x/dao/keeper/msg_server_distribution_result.go @@ -11,6 +11,12 @@ import ( "github.com/planetmint/planetmint-go/x/dao/types" ) +type Claims struct { + challenger map[string]uint64 + challengee map[string]uint64 + initiator map[string]uint64 +} + func (k msgServer) DistributionResult(goCtx context.Context, msg *types.MsgDistributionResult) (*types.MsgDistributionResultResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) @@ -47,11 +53,20 @@ func (k msgServer) DistributionResult(goCtx context.Context, msg *types.MsgDistr // Calculate the difference for a set of participants and clear out all past unresolved staged claims. func (k msgServer) clearUnresolvedClaims(ctx sdk.Context, start int64) (err error) { // calculate total amounts for current and future claims - currentAmounts, err := k.getClaims(ctx, start, ctx.BlockHeight()) + claims, err := k.getClaims(ctx, start, ctx.BlockHeight()) if err != nil { return err } + currentAmounts := make(map[string]uint64) + for address, amount := range claims.challenger { + currentAmounts[address] += amount + } + + for address, amount := range claims.challengee { + currentAmounts[address] += amount + } + totalAmounts := make(map[string]uint64) for participantAddress := range currentAmounts { stagedBalance := k.bankKeeper.GetBalance(ctx, sdk.MustAccAddressFromBech32(participantAddress), k.GetParams(ctx).StagedDenom) @@ -73,28 +88,29 @@ func (k msgServer) resolveStagedClaims(ctx sdk.Context, start int64, end int64) return err } - return k.convertOrderedClaim(ctx, popParticipantAmounts) + if err = k.convertOrderedClaim(ctx, popParticipantAmounts.initiator); err != nil { + return err + } + + if err = k.convertOrderedClaim(ctx, popParticipantAmounts.challenger); err != nil { + return err + } + + return k.convertOrderedClaim(ctx, popParticipantAmounts.challengee) } -func (k msgServer) getClaims(ctx sdk.Context, start int64, end int64) (claims map[string]uint64, err error) { +func (k msgServer) getClaims(ctx sdk.Context, start int64, end int64) (claims Claims, err error) { // lookup all challenges for a given range challenges, err := k.GetChallengeRange(ctx, start, end) if err != nil { return } - claims = make(map[string]uint64) + claims.initiator = make(map[string]uint64) + claims.challenger = make(map[string]uint64) + claims.challengee = make(map[string]uint64) for _, challenge := range challenges { - // if challenge not finished nobody has claims - if !challenge.GetFinished() { - continue - } - _, challengerAmt, challengeeAmt := util.GetPopReward(challenge.Height, k.GetParams(ctx).PopEpochs) - claims[challenge.Challenger] += challengerAmt - if challenge.GetSuccess() { - claims[challenge.Challengee] += challengeeAmt - } initiatorAddr, err := sdk.AccAddressFromBech32(challenge.Initiator) if err != nil { util.GetAppLogger().Error(ctx, "error converting initiator address") @@ -103,7 +119,17 @@ func (k msgServer) getClaims(ctx sdk.Context, start int64, end int64) (claims ma if !found { util.GetAppLogger().Error(ctx, "No PoP initiator reward found for height %v", challenge.GetHeight()) } - claims[initiatorAddr.String()] += validatorPopReward + claims.initiator[initiatorAddr.String()] += validatorPopReward + + // if challenge not finished only initiator has claims + if !challenge.GetFinished() { + continue + } + _, challengerAmt, challengeeAmt := util.GetPopReward(challenge.Height, k.GetParams(ctx).PopEpochs) + claims.challenger[challenge.Challenger] += challengerAmt + if challenge.GetSuccess() { + claims.challengee[challenge.Challengee] += challengeeAmt + } } return diff --git a/x/dao/keeper/msg_server_init_pop.go b/x/dao/keeper/msg_server_init_pop.go index 8bef7a5..75580a4 100644 --- a/x/dao/keeper/msg_server_init_pop.go +++ b/x/dao/keeper/msg_server_init_pop.go @@ -19,12 +19,28 @@ func (k msgServer) InitPop(goCtx context.Context, msg *types.MsgInitPop) (*types k.StoreChallenge(ctx, challenge) - amount := k.GetValidatorPoPReward(ctx) - k.StoreChallangeInitiatorReward(ctx, msg.GetHeight(), amount) - if util.IsValidatorBlockProposer(ctx, k.RootDir) { go util.SendMqttPopInitMessagesToServer(ctx, challenge) } + amount := k.GetValidatorPoPReward(ctx) + k.StoreChallangeInitiatorReward(ctx, msg.GetHeight(), amount) + + // TODO: expand err value in log + initiatorAddr, err := sdk.AccAddressFromBech32(msg.GetInitiator()) + if err != nil { + util.GetAppLogger().Error(ctx, "error converting initiator address: %v", err) + } + + valReward := sdk.NewCoins(sdk.NewCoin(k.GetParams(ctx).StagedDenom, sdk.NewIntFromUint64(amount))) + err = k.bankKeeper.MintCoins(ctx, types.ModuleName, valReward) + if err != nil { + util.GetAppLogger().Error(ctx, "error minting initiator rewards: %v", err) + } + + if err := k.sendRewards(ctx, initiatorAddr.String(), amount); err != nil { + util.GetAppLogger().Error(ctx, "failed to send rewards: %v", err) + } + return &types.MsgInitPopResponse{}, nil } diff --git a/x/dao/keeper/msg_server_report_pop_result.go b/x/dao/keeper/msg_server_report_pop_result.go index 81362ab..56d5150 100644 --- a/x/dao/keeper/msg_server_report_pop_result.go +++ b/x/dao/keeper/msg_server_report_pop_result.go @@ -44,12 +44,6 @@ func (k msgServer) ReportPopResult(goCtx context.Context, msg *types.MsgReportPo return nil, err } - _, err = sdk.AccAddressFromBech32(msg.Challenge.GetInitiator()) - if err != nil { - util.GetAppLogger().Error(ctx, "error converting initiator address") - return nil, errorsmod.Wrap(types.ErrInvalidPoPInitiator, "PoP initiator not hex encoded") - } - // update valid PoP Result reports err = k.updateChallenge(ctx, msg) if err != nil { @@ -80,12 +74,6 @@ func (k msgServer) issuePoPRewards(ctx sdk.Context, challenge types.Challenge) ( stagedCRDDL = stagedCRDDL.AddAmount(sdk.NewIntFromUint64(challengerAmt)) } - validatorPoPreward, found := k.getChallengeInitiatorReward(ctx, challenge.GetHeight()) - if !found { - util.GetAppLogger().Error(ctx, "No PoP initiator reward found for height %v", challenge.GetHeight()) - } - stagedCRDDL = stagedCRDDL.AddAmount(sdk.NewIntFromUint64(validatorPoPreward)) - err = k.bankKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(stagedCRDDL)) if err != nil { return @@ -102,12 +90,6 @@ func (k msgServer) handlePoP(ctx sdk.Context, challenge types.Challenge) (err er return } - initiatorAddr, _ := sdk.AccAddressFromBech32(challenge.Initiator) - err = k.sendRewards(ctx, initiatorAddr.String(), k.GetValidatorPoPReward(ctx)) - if err != nil { - return - } - if !challenge.GetSuccess() { return }