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

121 lines
3.5 KiB
Go

package keeper
import (
"colinear/x/colinearcore/math"
"colinear/x/colinearcore/memdb"
"colinear/x/colinearcore/types"
"log"
"math/big"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/pkg/errors"
)
func (k Keeper) AuctionIsExpired(ctx sdk.Context, auctionId string) (bool, error) {
auction, found := k.GetAuction(ctx, auctionId)
// make sure the auction exists on-chain
if !found {
return true, errors.Errorf("auction %s not found", auctionId)
}
return uint64(ctx.BlockHeight()) >= auction.Deadline, nil
}
func (k Keeper) FinalizeExpiredAuctions(ctx sdk.Context) {
memdb.AuctionDB.ForEachAuctionBidList(func(auctionId string) error {
auction, found := k.GetAuction(ctx, auctionId)
// make sure the auction exists on-chain
if !found {
return errors.Errorf("auction %s not found", auctionId)
}
if uint64(ctx.BlockHeight()) >= auction.Deadline {
var err error
auction.Best, err = memdb.AuctionDB.GetLowestBid(auctionId)
if err != nil {
return errors.Errorf("could not get highest bid for auction %s: %s", auctionId, err)
}
// Remaining Unpaid: Full bid amount
auction.Remaining = auction.Best.Amount
// clear auction bids
if err := memdb.AuctionDB.ClearAuctionBids(auctionId); err != nil {
return errors.Errorf("failed to clear auction from memcache: %s", err)
}
// clear verified provider list; swallow error since this isn't critical for now
_ = memdb.AuctionDB.ClearVerifiedProviders(auctionId)
// if err := memdb.AuctionDB.ClearVerifiedProviders(auctionId); err != nil {
// return errors.Errorf("failed to clear verified providers for auction %s: %s", auctionId, err)
// }
// pay out unpaid remainder to auction creator
ceiling := new(big.Int)
ceiling.SetString(auction.Ceiling, 10)
lowestBidAmt := new(big.Int)
lowestBidAmt.SetString(auction.Best.Amount, 10)
// only pay out if there is a difference
if ceiling.Cmp(lowestBidAmt) == 1 {
amtRemaining := new(big.Int)
amtRemaining.Sub(ceiling, lowestBidAmt)
coins := sdk.NewCoins(sdk.NewCoin(
auction.Denom,
sdk.NewIntFromBigInt(amtRemaining),
))
recipAddr, err := sdk.AccAddressFromBech32(auction.Owner)
if err != nil {
return errors.Errorf("failed to parse address %s", auction.Owner)
}
if err := k.bank.SendCoinsFromModuleToAccount(ctx, types.ModuleName, recipAddr, coins); err != nil {
log.Printf("Failed to send coins from module: %s\n", err)
// log.Fatalf("Failed to send coins from module: %s\n", err)
}
}
// lease period starts now
auction.LeaseStart = uint64(ctx.BlockTime().Unix())
// end auction
k.SetAuction(ctx, auction)
}
return nil
})
}
func (k *Keeper) PayAuctionAmountDue(ctx sdk.Context, auctionId string) error {
auction, found := k.GetAuction(ctx, auctionId)
if !found {
return errors.Errorf("auction %s not found", auctionId)
}
blockTime := ctx.BlockTime()
deadline := time.Unix(int64(auction.Deadline), 0)
if blockTime.After(deadline) {
return nil
} else {
amtTotal := new(big.Int)
amtTotal.SetString(auction.Best.Amount, 10)
amtRemaining := new(big.Int)
amtTotal.SetString(auction.Remaining, 10)
amt, err := math.CalcAmountVestableLinear(
amtTotal,
amtRemaining,
ctx.BlockTime(),
time.Unix(int64(auction.LeaseStart), 0),
time.Unix(int64(auction.LeaseEnd), 0),
)
if err != nil {
return err
}
coins := sdk.NewCoins(sdk.NewCoin(auction.Denom, sdk.NewIntFromBigInt(amt)))
err = k.bank.SendCoinsFromModuleToAccount(ctx, "colinear", sdk.AccAddress(auction.Best.Owner), coins)
return err
}
}