gpu-compute-chain/x/colinearcore/keeper/msg_server_new_bid.go

109 lines
3.2 KiB
Go
Raw Normal View History

2022-08-28 10:57:06 -07:00
package keeper
import (
"context"
2022-09-07 16:49:51 -07:00
"errors"
2022-08-28 13:28:25 -07:00
"fmt"
"math/big"
"reflect"
2022-08-28 10:57:06 -07:00
2022-09-07 16:49:51 -07:00
"colinear/x/colinearcore/auctionconfig"
2022-09-06 15:18:09 -07:00
"colinear/x/colinearcore/memdb"
"colinear/x/colinearcore/types"
2022-08-28 13:28:25 -07:00
2022-08-28 10:57:06 -07:00
sdk "github.com/cosmos/cosmos-sdk/types"
)
func (k msgServer) NewBid(goCtx context.Context, msg *types.MsgNewBid) (*types.MsgNewBidResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
2022-09-07 16:49:51 -07:00
lockedUsers, ok := k.Keeper.GetLockedUsers(ctx)
if !ok {
return nil, errors.New("unable to read locked providers (uninitialized)")
}
if lockedAmtStr, ok := lockedUsers.Users[msg.Creator]; !ok {
return nil, fmt.Errorf("provider has not locked CLR tokens (min: %d uCLR)", auctionconfig.ProviderMinLockedUClr)
} else {
lockedAmt := new(big.Int)
lockedAmt.SetString(lockedAmtStr, 10)
required := big.NewInt(auctionconfig.ProviderMinLockedUClr)
if lockedAmt.Cmp(required) == -1 {
return nil, fmt.Errorf("provider has not locked enough CLR tokens (min: %d uCLR, locked: %s)", auctionconfig.ProviderMinLockedUClr, lockedAmt.String())
}
}
auction, found := k.Keeper.GetAuction(ctx, msg.AuctionIndex)
2022-08-28 13:28:25 -07:00
if !found {
return nil, fmt.Errorf("didn't find auction of index %s", msg.AuctionIndex)
}
2022-08-31 15:40:28 -07:00
auctionExpired, err := k.Keeper.AuctionIsExpired(ctx, msg.AuctionIndex)
if err != nil {
return nil, fmt.Errorf("error while checking auction %s expiry status: %s", msg.AuctionIndex, err)
}
if auctionExpired {
return nil, fmt.Errorf("auction %s is expired", msg.AuctionIndex)
}
if verProvs, err := memdb.AuctionDB.GetVerifiedProviders(msg.AuctionIndex); err == nil {
if len(verProvs) == 0 {
goto bidderVerified
} else {
for _, provider := range verProvs {
if msg.Creator == provider {
goto bidderVerified
}
}
return nil, fmt.Errorf("bid sender is not verified by the creator of auction %s", auction.Index)
}
}
bidderVerified:
2022-08-28 13:28:25 -07:00
amt := new(big.Int)
amt, ok = amt.SetString(msg.Amount, 10)
if !ok {
return nil, fmt.Errorf("failed to convert `%s` to a large integer", msg.Amount)
}
if amt.Sign() != 1 {
return nil, fmt.Errorf("bid amount must be greater than 0")
}
ceiling := new(big.Int)
ceiling.SetString(auction.Ceiling, 10)
if amt.Cmp(ceiling) == 1 {
return nil, fmt.Errorf("bid amount cannot be greater than auction price ceiling (%s)", auction.Ceiling)
}
lowestBid, err := memdb.AuctionDB.GetLowestBid(msg.AuctionIndex)
// we manually handle KeyNotFound in GetHighestBid, so should return (nil, nil) if not found
2022-08-30 12:30:17 -07:00
if err != nil {
return nil, fmt.Errorf("failed to get lowest bid: %s", reflect.TypeOf(err))
2022-08-28 13:28:25 -07:00
}
if lowestBid != nil {
amtPrev := new(big.Int)
amtPrev, ok = amtPrev.SetString(lowestBid.Amount, 10)
if !ok { // this should have been checked before, but whatever
return nil, fmt.Errorf("failed to convert max bid (%s) to a large integer", msg.Amount)
}
if amt.Cmp(amtPrev) != -1 {
return nil, fmt.Errorf("bid amount must be less than current lowest bid (%s)", amtPrev)
}
2022-08-28 13:28:25 -07:00
}
2022-09-07 13:25:57 -07:00
// check that user has locked minimum required CLR
2022-08-28 13:28:25 -07:00
bid := &types.Bid{
Amount: msg.Amount,
Owner: msg.Creator,
}
if err := memdb.AuctionDB.AddBid(msg.AuctionIndex, bid); err != nil {
return nil, fmt.Errorf("failed to add bid: %s", err)
}
2022-08-30 12:30:17 -07:00
2022-08-28 10:57:06 -07:00
return &types.MsgNewBidResponse{}, nil
}