package keeper import ( "context" "errors" "fmt" "math/big" "strconv" "cosmos-test/x/cosmostest/auctionconfig" "cosmos-test/x/cosmostest/types" sdk "github.com/cosmos/cosmos-sdk/types" ) func (k msgServer) NewAuction(goCtx context.Context, msg *types.MsgNewAuction) (*types.MsgNewAuctionResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) next, found := k.Keeper.GetNextAuction(ctx) if !found { return nil, errors.New("unable to get next auction index") } index := strconv.FormatUint(next.AuctionId, 10) auctionLen := msg.LeaseEnd - uint64(ctx.BlockTime().Unix()) if auctionLen < auctionconfig.MinLeasePeriod { return nil, fmt.Errorf( "Auction length %d is below min lease period of %d", auctionLen, auctionconfig.MinLeasePeriod, ) } if auctionLen > auctionconfig.MaxLeasePeriod { return nil, fmt.Errorf( "Auction length %d is above max lease period of %d", auctionLen, auctionconfig.MaxLeasePeriod, ) } auction := types.Auction{ Index: index, Name: msg.Name, Description: msg.Description, // best bid -> null // Best: new(types.Bid), Deadline: uint64(ctx.BlockHeight()) + auctionconfig.AuctionTime, Denom: msg.Denom, Owner: msg.Creator, Ceiling: msg.Ceiling, // lease start -> null // instead, initialize when auction is finalized // LeaseStart: uint64(ctx.BlockTime().Unix()), LeaseEnd: msg.LeaseEnd, // remaining payout -> null // Remaining: "0", } senderAddr, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { return nil, fmt.Errorf("sender address `%s` format invalid (bech32 required)", msg.Creator) } spendable := k.bank.SpendableCoins(ctx, senderAddr) // if balance does not exceed or equal proposed auction ceiling... ceiling := new(big.Int) ceiling.SetString(auction.Ceiling, 10) if spendable.AmountOf(auction.Denom).BigInt().Cmp(ceiling) == -1 { return nil, fmt.Errorf("not enough balance to set ceiling %s%s", msg.Ceiling, auction.Denom) } coins := sdk.NewCoins(sdk.Coin{ Amount: sdk.NewIntFromBigInt(ceiling), Denom: auction.Denom, }) if err := k.Keeper.bank.SendCoinsFromAccountToModule(ctx, senderAddr, types.ModuleName, coins); err != nil { return nil, fmt.Errorf("failed to transfer %s%s", auction.Ceiling, auction.Denom) } k.Keeper.SetAuction(ctx, auction) next.AuctionId++ k.Keeper.SetNextAuction(ctx, types.NextAuction{AuctionId: next.AuctionId}) return &types.MsgNewAuctionResponse{ AuctionId: strconv.FormatUint(next.AuctionId, 10), }, nil }