mirror of
https://github.com/planetmint/planetmint-go.git
synced 2025-03-30 15:08:28 +00:00
feat: add unresolved claim cleanup
Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>
This commit is contained in:
parent
764d1158dc
commit
01100ec219
@ -10,9 +10,11 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
sdkmath "cosmossdk.io/math"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/planetmint/planetmint-go/lib"
|
||||
"github.com/planetmint/planetmint-go/monitor"
|
||||
"github.com/planetmint/planetmint-go/testutil"
|
||||
@ -85,6 +87,17 @@ func (s *SelectionE2ETestSuite) SetupSuite() {
|
||||
daoGenState.Params.ClaimAddress = valAddr.String()
|
||||
s.cfg.GenesisState[daotypes.ModuleName] = s.cfg.Codec.MustMarshalJSON(&daoGenState)
|
||||
|
||||
// setting up stagedClaims that are not part of PoP issuance (i.e.: past unresolved claims)
|
||||
machineBalances := []banktypes.Balance{
|
||||
{Address: machines[0].address, Coins: sdk.NewCoins(sdk.NewCoin(daoGenState.Params.StagedDenom, sdkmath.NewInt(10000)))},
|
||||
{Address: machines[1].address, Coins: sdk.NewCoins(sdk.NewCoin(daoGenState.Params.StagedDenom, sdkmath.NewInt(10000)))},
|
||||
}
|
||||
|
||||
var bankGenState banktypes.GenesisState
|
||||
s.cfg.Codec.MustUnmarshalJSON(s.cfg.GenesisState[banktypes.ModuleName], &bankGenState)
|
||||
bankGenState.Balances = append(bankGenState.Balances, machineBalances...)
|
||||
s.cfg.GenesisState[banktypes.ModuleName] = s.cfg.Codec.MustMarshalJSON(&bankGenState)
|
||||
|
||||
s.network = network.Load(s.T(), s.cfg)
|
||||
}
|
||||
|
||||
@ -198,7 +211,7 @@ func (s *SelectionE2ETestSuite) VerifyTokens(token string) {
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
assert.Contains(s.T(), out.String(), token)
|
||||
assert.Equal(s.T(), "amount: \"18279452050\"\ndenom: "+token+"\n", out.String()) // Total supply 2 * 7990867578 (total supply) + 1 * 1997716894 (challenger) + 3 * 100000000 (validator) = 17979452050
|
||||
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
|
||||
|
||||
out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, bank.GetBalancesCmd(), []string{
|
||||
machines[0].address,
|
||||
@ -206,7 +219,7 @@ func (s *SelectionE2ETestSuite) VerifyTokens(token string) {
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
assert.Contains(s.T(), out.String(), token)
|
||||
assert.Equal(s.T(), "amount: \"5993150682\"\ndenom: "+token+"\n", out.String()) // 3 * 1997716894 = 5993150682
|
||||
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,
|
||||
@ -214,7 +227,7 @@ func (s *SelectionE2ETestSuite) VerifyTokens(token string) {
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
assert.Contains(s.T(), out.String(), token)
|
||||
assert.Equal(s.T(), "amount: \"11986301368\"\ndenom: "+token+"\n", out.String()) // 2 * 5993150684 = 11986301368
|
||||
assert.Equal(s.T(), "amount: \"11986311368\"\ndenom: "+token+"\n", out.String()) // 2 * 5993150684 + 1 * 10000 = 11986311368
|
||||
|
||||
out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, bank.GetBalancesCmd(), []string{
|
||||
val.Address.String(),
|
||||
@ -320,11 +333,11 @@ func (s *SelectionE2ETestSuite) TestTokenRedeemClaim() {
|
||||
// QueryRedeemClaim
|
||||
qOut, err := clitestutil.ExecTestCLICmd(val.ClientCtx, daocli.CmdShowRedeemClaim(), []string{"liquidAddress", "0"})
|
||||
s.Require().NoError(err)
|
||||
assert.Equal(s.T(), "redeemClaim:\n amount: \"5993150682\"\n beneficiary: liquidAddress\n confirmed: true\n creator: plmnt1kp93kns6hs2066d8qw0uz84fw3vlthewt2ck6p\n id: \"0\"\n liquidTxHash: \"0000000000000000000000000000000000000000000000000000000000000000\"\n", qOut.String())
|
||||
assert.Equal(s.T(), "redeemClaim:\n amount: \"5993160682\"\n beneficiary: liquidAddress\n confirmed: true\n creator: plmnt1kp93kns6hs2066d8qw0uz84fw3vlthewt2ck6p\n id: \"0\"\n liquidTxHash: \"0000000000000000000000000000000000000000000000000000000000000000\"\n", qOut.String())
|
||||
|
||||
qOut, err = clitestutil.ExecTestCLICmd(val.ClientCtx, daocli.CmdRedeemClaimByLiquidTxHash(), []string{"0000000000000000000000000000000000000000000000000000000000000000"})
|
||||
s.Require().NoError(err)
|
||||
assert.Equal(s.T(), "redeemClaim:\n amount: \"5993150682\"\n beneficiary: liquidAddress\n confirmed: true\n creator: plmnt1kp93kns6hs2066d8qw0uz84fw3vlthewt2ck6p\n id: \"0\"\n liquidTxHash: \"0000000000000000000000000000000000000000000000000000000000000000\"\n", qOut.String())
|
||||
assert.Equal(s.T(), "redeemClaim:\n amount: \"5993160682\"\n beneficiary: liquidAddress\n confirmed: true\n creator: plmnt1kp93kns6hs2066d8qw0uz84fw3vlthewt2ck6p\n id: \"0\"\n liquidTxHash: \"0000000000000000000000000000000000000000000000000000000000000000\"\n", qOut.String())
|
||||
|
||||
// Make sure "Publish" has been called with PoPInit cmnd
|
||||
calls := mocks.GetCallLog()
|
||||
|
@ -2,6 +2,7 @@ package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
@ -26,6 +27,10 @@ func (k msgServer) DistributionResult(goCtx context.Context, msg *types.MsgDistr
|
||||
distribution.EarlyInvAddr = msg.EarlyInvestorTxID
|
||||
distribution.StrategicTxID = msg.StrategicTxID
|
||||
|
||||
if err := k.clearUnresolvedClaims(ctx, distribution.FirstPop); err != nil {
|
||||
util.GetAppLogger().Error(ctx, "error while clearing unresolved claims for heights %d-%d: %v", distribution.FirstPop, distribution.LastPop, err)
|
||||
}
|
||||
|
||||
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)
|
||||
@ -37,14 +42,48 @@ func (k msgServer) DistributionResult(goCtx context.Context, msg *types.MsgDistr
|
||||
return &types.MsgDistributionResultResponse{}, nil
|
||||
}
|
||||
|
||||
func (k msgServer) resolveStagedClaims(ctx sdk.Context, start int64, end int64) (err error) {
|
||||
// lookup all challenges since the last distribution
|
||||
challenges, err := k.GetChallengeRange(ctx, start, end)
|
||||
// clearUnresolvedClaims checks for all Challenge participants starting from a given height.
|
||||
// An accounts stagedDenom amount should always be 0 except for claims that have not yet been reissued.
|
||||
// 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())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
popParticipants := make(map[string]uint64)
|
||||
totalAmounts := make(map[string]uint64)
|
||||
for participantAddress := range currentAmounts {
|
||||
stagedBalance := k.bankKeeper.GetBalance(ctx, sdk.MustAccAddressFromBech32(participantAddress), k.GetParams(ctx).StagedDenom)
|
||||
totalAmounts[participantAddress] = stagedBalance.Amount.Uint64()
|
||||
}
|
||||
|
||||
// calculate difference to account balance
|
||||
for participantAddress := range totalAmounts {
|
||||
totalAmounts[participantAddress] -= currentAmounts[participantAddress]
|
||||
}
|
||||
|
||||
return k.convertOrderedClaim(ctx, totalAmounts)
|
||||
}
|
||||
|
||||
// resolveStagedClaims converts staged claims to claims in an ordered fashion for a given range
|
||||
func (k msgServer) resolveStagedClaims(ctx sdk.Context, start int64, end int64) (err error) {
|
||||
popParticipantAmounts, err := k.getClaims(ctx, start, end)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return k.convertOrderedClaim(ctx, popParticipantAmounts)
|
||||
}
|
||||
|
||||
func (k msgServer) getClaims(ctx sdk.Context, start int64, end int64) (claims map[string]uint64, 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)
|
||||
|
||||
for _, challenge := range challenges {
|
||||
// if challenge not finished nobody has claims
|
||||
@ -52,9 +91,9 @@ func (k msgServer) resolveStagedClaims(ctx sdk.Context, start int64, end int64)
|
||||
continue
|
||||
}
|
||||
_, challengerAmt, challengeeAmt := util.GetPopReward(challenge.Height, k.GetParams(ctx).PopEpochs)
|
||||
popParticipants[challenge.Challenger] += challengerAmt
|
||||
claims[challenge.Challenger] += challengerAmt
|
||||
if challenge.GetSuccess() {
|
||||
popParticipants[challenge.Challengee] += challengeeAmt
|
||||
claims[challenge.Challengee] += challengeeAmt
|
||||
}
|
||||
initiatorAddr, err := sdk.AccAddressFromBech32(challenge.Initiator)
|
||||
if err != nil {
|
||||
@ -64,16 +103,22 @@ func (k msgServer) resolveStagedClaims(ctx sdk.Context, start int64, end int64)
|
||||
if !found {
|
||||
util.GetAppLogger().Error(ctx, "No PoP initiator reward found for height %v", challenge.GetHeight())
|
||||
}
|
||||
popParticipants[initiatorAddr.String()] += validatorPopReward
|
||||
claims[initiatorAddr.String()] += validatorPopReward
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (k msgServer) convertOrderedClaim(ctx sdk.Context, claims map[string]uint64) (err error) {
|
||||
// second data structure because map iteration order is not guaranteed in GO
|
||||
keys := make([]string, 0)
|
||||
for p := range popParticipants {
|
||||
keys = append(keys, p)
|
||||
for accountAddress := range claims {
|
||||
keys = append(keys, accountAddress)
|
||||
}
|
||||
for _, p := range keys {
|
||||
err = k.convertAccountClaim(ctx, p, popParticipants[p])
|
||||
|
||||
sort.Strings(keys)
|
||||
for _, accountAddress := range keys {
|
||||
err = k.convertAccountClaim(ctx, accountAddress, claims[accountAddress])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user