Skip to content

Commit

Permalink
move to []PayoutPairs from map
Browse files Browse the repository at this point in the history
  • Loading branch information
Reecepbcups committed May 30, 2024
1 parent 4925841 commit cda6b08
Show file tree
Hide file tree
Showing 8 changed files with 1,063 additions and 546 deletions.
1,041 changes: 705 additions & 336 deletions api/manifest/v1/tx.pulsar.go

Large diffs are not rendered by default.

14 changes: 12 additions & 2 deletions proto/manifest/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,23 @@ message MsgPayout {
// authority is the address of the controlling account.
string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];

// payout is the amount of tokens paid to accounts.
map<string, cosmos.base.v1beta1.Coin> payouts = 2 [
// payout_pairs are the pairs of addresses and coins to be paid out.
repeated PayoutPair payout_pairs = 2 [
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true
];
}

message PayoutPair {
string address = 1;
cosmos.base.v1beta1.Coin coin = 2 [
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true,
(amino.encoding) = "legacy_coin",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.Coin"
];
}

// MsgPayoutResponse defines the response structure for executing a MsgPayout message.
message MsgPayoutResponse {}

Expand Down
13 changes: 8 additions & 5 deletions x/manifest/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ func MsgPayout() *cobra.Command {
}

msg := &types.MsgPayout{
Authority: authority.String(),
Payouts: payoutPairs,
Authority: authority.String(),
PayoutPairs: payoutPairs,
}

if err := msg.Validate(); err != nil {
Expand Down Expand Up @@ -108,8 +108,8 @@ func MsgBurnCoins() *cobra.Command {

// fromStrToPayout converts a string to a slice of StakeHolders.
// ex: manifest1abc:50_000umfx,manifest1xyz:1_000_000umfx
func fromStrToPayout(s string) (map[string]sdk.Coin, error) {
payouts := make(map[string]sdk.Coin, 0)
func fromStrToPayout(s string) ([]types.PayoutPair, error) {
payouts := make([]types.PayoutPair, 0)

s = strings.ReplaceAll(s, "_", "")

Expand All @@ -134,7 +134,10 @@ func fromStrToPayout(s string) (map[string]sdk.Coin, error) {
return nil, fmt.Errorf("invalid coin: %s for address: %s", strCoin, strAddr)
}

payouts[strAddr] = coin
payouts = append(payouts, types.PayoutPair{
Address: strAddr,
Coin: coin,
})
}

return payouts, nil
Expand Down
29 changes: 16 additions & 13 deletions x/manifest/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,33 +88,36 @@ func (k *Keeper) ExportGenesis(ctx context.Context) *types.GenesisState {
}

// PayoutStakeholders mints and sends coins to stakeholders.
func (k Keeper) PayoutStakeholders(ctx context.Context, payouts map[string]sdk.Coin) error {
for addr, p := range payouts {
addr := addr
func (k Keeper) PayoutStakeholders(ctx context.Context, payouts []types.PayoutPair) error {
for _, p := range payouts {
p := p
addr := p.Address
coin := p.Coin

sdkAddr, err := sdk.AccAddressFromBech32(addr)
if err != nil {
return err
}

// ensure p is valid
if !p.IsValid() {
if !coin.IsValid() {
return fmt.Errorf("invalid payout: %v for address: %s", p, addr)
}

// mint & send coins
coins := sdk.NewCoins(p)
if err := k.bankKeeper.MintCoins(ctx, types.ModuleName, coins); err != nil {
if err := k.mintCoinsToAccount(ctx, sdkAddr, coin); err != nil {
return err
}

if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sdkAddr, coins); err != nil {
return err
}

k.Logger().Info("Payout", "address", addr, "amount", coins)
k.Logger().Info("Payout", "address", addr, "amount", coin)
}

return nil
}

func (k Keeper) mintCoinsToAccount(ctx context.Context, sdkAddr sdk.AccAddress, coin sdk.Coin) error {
coins := sdk.NewCoins(coin)
if err := k.bankKeeper.MintCoins(ctx, types.ModuleName, coins); err != nil {
return err
}

return k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sdkAddr, coins)
}
2 changes: 1 addition & 1 deletion x/manifest/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (ms msgServer) Payout(ctx context.Context, req *types.MsgPayout) (*types.Ms
return nil, fmt.Errorf("invalid payout message: %w", err)
}

return nil, ms.k.PayoutStakeholders(ctx, req.Payouts)
return nil, ms.k.PayoutStakeholders(ctx, req.PayoutPairs)
}

// BurnHeldBalance implements types.MsgServer.
Expand Down
42 changes: 23 additions & 19 deletions x/manifest/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,52 +29,52 @@ func TestPerformPayout(t *testing.T) {
type testcase struct {
name string
sender string
payouts map[string]sdk.Coin
payouts []types.PayoutPair
shouldFail bool
}

cases := []testcase{
{
name: "success; payout token to 3 stakeholders",
sender: authority.String(),
payouts: map[string]sdk.Coin{
acc.String(): sdk.NewCoin("umfx", sdkmath.NewInt(1)),
acc2.String(): sdk.NewCoin("umfx", sdkmath.NewInt(2)),
acc3.String(): sdk.NewCoin("umfx", sdkmath.NewInt(3)),
payouts: []types.PayoutPair{
types.NewPayoutPair(acc, "umfx", 1),
types.NewPayoutPair(acc2, "umfx", 2),
types.NewPayoutPair(acc3, "umfx", 3),
},
},
{
name: "fail; bad authority",
sender: acc.String(),
payouts: map[string]sdk.Coin{
acc.String(): sdk.NewCoin("umfx", sdkmath.NewInt(1)),
payouts: []types.PayoutPair{
types.NewPayoutPair(acc, "umfx", 1),
},
shouldFail: true,
},
{
name: "fail; bad bech32 authority",
sender: "bad",
payouts: map[string]sdk.Coin{
acc.String(): sdk.NewCoin("umfx", sdkmath.NewInt(1)),
payouts: []types.PayoutPair{
types.NewPayoutPair(acc, "umfx", 1),
},
shouldFail: true,
},
{
name: "fail; payout to bad address",
sender: authority.String(),
payouts: map[string]sdk.Coin{
acc.String(): sdk.NewCoin("umfx", sdkmath.NewInt(1)),
"badaddr": sdk.NewCoin("umfx", sdkmath.NewInt(2)),
acc3.String(): sdk.NewCoin("umfx", sdkmath.NewInt(3)),
payouts: []types.PayoutPair{
types.NewPayoutPair(acc, "umfx", 1),
{Address: "badaddr", Coin: sdk.NewCoin("umfx", sdkmath.NewInt(2))},
types.NewPayoutPair(acc3, "umfx", 3),
},
shouldFail: true,
},
{
name: "fail; payout with a 0 token",
sender: authority.String(),
payouts: map[string]sdk.Coin{
acc.String(): sdk.NewCoin("umfx", sdkmath.NewInt(1)),
acc2.String(): sdk.NewCoin("umfx", sdkmath.NewInt(0)),
payouts: []types.PayoutPair{
types.NewPayoutPair(acc, "umfx", 1),
types.NewPayoutPair(acc2, "umfx", 0),
},
shouldFail: true,
},
Expand All @@ -85,8 +85,8 @@ func TestPerformPayout(t *testing.T) {

t.Run(c.name, func(t *testing.T) {
payoutMsg := &types.MsgPayout{
Authority: c.sender,
Payouts: c.payouts,
Authority: c.sender,
PayoutPairs: c.payouts,
}

_, err := ms.Payout(f.Ctx, payoutMsg)
Expand All @@ -96,7 +96,11 @@ func TestPerformPayout(t *testing.T) {
}
require.NoError(t, err)

for addr, coin := range c.payouts {
for _, p := range c.payouts {
p := p
addr := p.Address
coin := p.Coin

accAddr, err := sdk.AccAddressFromBech32(addr)
require.NoError(t, err)

Expand Down
25 changes: 19 additions & 6 deletions x/manifest/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
fmt "fmt"

"cosmossdk.io/errors"
"cosmossdk.io/math"

sdk "github.com/cosmos/cosmos-sdk/types"
)
Expand Down Expand Up @@ -50,11 +51,18 @@ var _ sdk.Msg = &MsgPayout{}

func NewMsgPayout(
sender sdk.Address,
payouts map[string]sdk.Coin,
payouts []PayoutPair,
) *MsgPayout {
return &MsgPayout{
Authority: sender.String(),
Payouts: payouts,
Authority: sender.String(),
PayoutPairs: payouts,
}
}

func NewPayoutPair(addr sdk.AccAddress, denom string, amt int64) PayoutPair {
return PayoutPair{
Address: addr.String(),
Coin: sdk.NewCoin(denom, math.NewInt(amt)),
}
}

Expand All @@ -81,11 +89,16 @@ func (msg *MsgPayout) Validate() error {
return errors.Wrap(err, "invalid authority address")
}

if len(msg.Payouts) == 0 {
return fmt.Errorf("accounts cannot be empty")
if len(msg.PayoutPairs) == 0 {
return fmt.Errorf("payouts cannot be empty")
}

for addr, coin := range msg.Payouts {
for _, p := range msg.PayoutPairs {
p := p

addr := p.Address
coin := p.Coin

if _, err := sdk.AccAddressFromBech32(addr); err != nil {
return errors.Wrapf(err, "invalid address %s", addr)
}
Expand Down
Loading

0 comments on commit cda6b08

Please sign in to comment.