[R4R] Custom sdk.Error types for the auction module (#285)

* Custom sdk.Error types for the auction module

* Requested changes: naming conventions, error message text
This commit is contained in:
Denali Marsh 2020-01-15 11:39:55 +01:00 committed by Kevin Davis
parent 8128a680cc
commit ba80b508ab
8 changed files with 159 additions and 54 deletions

View File

@ -11,6 +11,19 @@ import (
) )
const ( const (
DefaultCodespace = types.DefaultCodespace
CodeInvalidInitialAuctionID = types.CodeInvalidInitialAuctionID
CodeUnrecognizedAuctionType = types.CodeUnrecognizedAuctionType
CodeAuctionNotFound = types.CodeAuctionNotFound
CodeAuctionHasNotExpired = types.CodeAuctionHasNotExpired
CodeAuctionHasExpired = types.CodeAuctionHasExpired
CodeInvalidBidDenom = types.CodeInvalidBidDenom
CodeInvalidLotDenom = types.CodeInvalidLotDenom
CodeBidTooSmall = types.CodeBidTooSmall
CodeBidTooLarge = types.CodeBidTooLarge
CodeLotTooLarge = types.CodeLotTooLarge
CodeCollateralAuctionIsInReversePhase = types.CodeCollateralAuctionIsInReversePhase
CodeCollateralAuctionIsInForwardPhase = types.CodeCollateralAuctionIsInForwardPhase
ModuleName = types.ModuleName ModuleName = types.ModuleName
StoreKey = types.StoreKey StoreKey = types.StoreKey
RouterKey = types.RouterKey RouterKey = types.RouterKey

View File

@ -17,8 +17,7 @@ func NewHandler(keeper Keeper) sdk.Handler {
case MsgPlaceBid: case MsgPlaceBid:
return handleMsgPlaceBid(ctx, keeper, msg) return handleMsgPlaceBid(ctx, keeper, msg)
default: default:
errMsg := fmt.Sprintf("Unrecognized auction msg type: %T", msg) return sdk.ErrUnknownRequest(fmt.Sprintf("Unrecognized auction msg type: %T", msg)).Result()
return sdk.ErrUnknownRequest(errMsg).Result()
} }
} }
} }

View File

@ -53,7 +53,7 @@ func (k Keeper) StartDebtAuction(ctx sdk.Context, buyer string, bid sdk.Coin, in
// This auction type mints coins at close. Need to check module account has minting privileges to avoid potential err in endblocker. // This auction type mints coins at close. Need to check module account has minting privileges to avoid potential err in endblocker.
macc := k.supplyKeeper.GetModuleAccount(ctx, buyer) macc := k.supplyKeeper.GetModuleAccount(ctx, buyer)
if !macc.HasPermission(supply.Minter) { if !macc.HasPermission(supply.Minter) {
return 0, sdk.ErrInternal("module does not have minting permissions") return 0, types.ErrInvalidModulePermissions(k.codespace, supply.Minter)
} }
err := k.supplyKeeper.SendCoinsFromModuleToModule(ctx, buyer, types.ModuleName, sdk.NewCoins(debt)) err := k.supplyKeeper.SendCoinsFromModuleToModule(ctx, buyer, types.ModuleName, sdk.NewCoins(debt))
@ -124,12 +124,12 @@ func (k Keeper) PlaceBid(ctx sdk.Context, auctionID uint64, bidder sdk.AccAddres
auction, found := k.GetAuction(ctx, auctionID) auction, found := k.GetAuction(ctx, auctionID)
if !found { if !found {
return sdk.ErrInternal("auction doesn't exist") return types.ErrAuctionNotFound(k.codespace, auctionID)
} }
// validation common to all auctions // validation common to all auctions
if ctx.BlockTime().After(auction.GetEndTime()) { if ctx.BlockTime().After(auction.GetEndTime()) {
return sdk.ErrInternal("auction has closed") return types.ErrAuctionHasExpired(k.codespace, auctionID)
} }
// move coins and return updated auction // move coins and return updated auction
@ -154,7 +154,7 @@ func (k Keeper) PlaceBid(ctx sdk.Context, auctionID uint64, bidder sdk.AccAddres
return err return err
} }
default: default:
panic(fmt.Sprintf("unrecognized auction type: %T", auction)) return types.ErrUnrecognizedAuctionType(k.codespace)
} }
k.SetAuction(ctx, updatedAuction) k.SetAuction(ctx, updatedAuction)
@ -166,10 +166,10 @@ func (k Keeper) PlaceBid(ctx sdk.Context, auctionID uint64, bidder sdk.AccAddres
func (k Keeper) PlaceBidSurplus(ctx sdk.Context, a types.SurplusAuction, bidder sdk.AccAddress, bid sdk.Coin) (types.SurplusAuction, sdk.Error) { func (k Keeper) PlaceBidSurplus(ctx sdk.Context, a types.SurplusAuction, bidder sdk.AccAddress, bid sdk.Coin) (types.SurplusAuction, sdk.Error) {
// Validate new bid // Validate new bid
if bid.Denom != a.Bid.Denom { if bid.Denom != a.Bid.Denom {
return a, sdk.ErrInternal("bid denom doesn't match auction") return a, types.ErrInvalidBidDenom(k.codespace, bid.Denom, a.Bid.Denom)
} }
if !a.Bid.IsLT(bid) { if !a.Bid.IsLT(bid) {
return a, sdk.ErrInternal("bid not greater than last bid") return a, types.ErrBidTooSmall(k.codespace, bid, a.Bid)
} }
// New bidder pays back old bidder // New bidder pays back old bidder
@ -220,16 +220,16 @@ func (k Keeper) PlaceBidSurplus(ctx sdk.Context, a types.SurplusAuction, bidder
func (k Keeper) PlaceForwardBidCollateral(ctx sdk.Context, a types.CollateralAuction, bidder sdk.AccAddress, bid sdk.Coin) (types.CollateralAuction, sdk.Error) { func (k Keeper) PlaceForwardBidCollateral(ctx sdk.Context, a types.CollateralAuction, bidder sdk.AccAddress, bid sdk.Coin) (types.CollateralAuction, sdk.Error) {
// Validate new bid // Validate new bid
if bid.Denom != a.Bid.Denom { if bid.Denom != a.Bid.Denom {
return a, sdk.ErrInternal("bid denom doesn't match auction") return a, types.ErrInvalidBidDenom(k.codespace, bid.Denom, a.Bid.Denom)
} }
if a.IsReversePhase() { if a.IsReversePhase() {
return a, sdk.ErrInternal("auction is not in forward phase") return a, types.ErrCollateralAuctionIsInReversePhase(k.codespace, a.ID)
} }
if !a.Bid.IsLT(bid) { if !a.Bid.IsLT(bid) {
return a, sdk.ErrInternal("auction in forward phase, new bid not higher than last bid") return a, types.ErrBidTooSmall(k.codespace, bid, a.Bid)
} }
if a.MaxBid.IsLT(bid) { if a.MaxBid.IsLT(bid) {
return a, sdk.ErrInternal("bid higher than max bid") return a, types.ErrBidTooLarge(k.codespace, bid, a.MaxBid)
} }
// New bidder pays back old bidder // New bidder pays back old bidder
@ -289,13 +289,13 @@ func (k Keeper) PlaceForwardBidCollateral(ctx sdk.Context, a types.CollateralAuc
func (k Keeper) PlaceReverseBidCollateral(ctx sdk.Context, a types.CollateralAuction, bidder sdk.AccAddress, lot sdk.Coin) (types.CollateralAuction, sdk.Error) { func (k Keeper) PlaceReverseBidCollateral(ctx sdk.Context, a types.CollateralAuction, bidder sdk.AccAddress, lot sdk.Coin) (types.CollateralAuction, sdk.Error) {
// Validate new bid // Validate new bid
if lot.Denom != a.Lot.Denom { if lot.Denom != a.Lot.Denom {
return a, sdk.ErrInternal("lot denom doesn't match auction") return a, types.ErrInvalidLotDenom(k.codespace, lot.Denom, a.Lot.Denom)
} }
if !a.IsReversePhase() { if !a.IsReversePhase() {
return a, sdk.ErrInternal("auction not in reverse phase") return a, types.ErrCollateralAuctionIsInForwardPhase(k.codespace, a.ID)
} }
if !lot.IsLT(a.Lot) { if !lot.IsLT(a.Lot) {
return a, sdk.ErrInternal("auction in reverse phase, new bid not less than previous amount") return a, types.ErrLotTooLarge(k.codespace, lot, a.Lot)
} }
// New bidder pays back old bidder // New bidder pays back old bidder
@ -349,10 +349,10 @@ func (k Keeper) PlaceReverseBidCollateral(ctx sdk.Context, a types.CollateralAuc
func (k Keeper) PlaceBidDebt(ctx sdk.Context, a types.DebtAuction, bidder sdk.AccAddress, lot sdk.Coin) (types.DebtAuction, sdk.Error) { func (k Keeper) PlaceBidDebt(ctx sdk.Context, a types.DebtAuction, bidder sdk.AccAddress, lot sdk.Coin) (types.DebtAuction, sdk.Error) {
// Validate new bid // Validate new bid
if lot.Denom != a.Lot.Denom { if lot.Denom != a.Lot.Denom {
return a, sdk.ErrInternal("lot denom doesn't match auction") return a, types.ErrInvalidLotDenom(k.codespace, lot.Denom, a.Lot.Denom)
} }
if !lot.IsLT(a.Lot) { if !lot.IsLT(a.Lot) {
return a, sdk.ErrInternal("lot not smaller than last lot") return a, types.ErrLotTooLarge(k.codespace, lot, a.Lot)
} }
// New bidder pays back old bidder // New bidder pays back old bidder
@ -407,11 +407,11 @@ func (k Keeper) CloseAuction(ctx sdk.Context, auctionID uint64) sdk.Error {
auction, found := k.GetAuction(ctx, auctionID) auction, found := k.GetAuction(ctx, auctionID)
if !found { if !found {
return sdk.ErrInternal("auction doesn't exist") return types.ErrAuctionNotFound(k.codespace, auctionID)
} }
if ctx.BlockTime().Before(auction.GetEndTime()) { if ctx.BlockTime().Before(auction.GetEndTime()) {
return sdk.ErrInternal(fmt.Sprintf("auction can't be closed as curent block time (%v) is under auction end time (%v)", ctx.BlockTime(), auction.GetEndTime())) return types.ErrAuctionHasNotExpired(k.codespace, ctx.BlockTime(), auction.GetEndTime())
} }
// payout to the last bidder // payout to the last bidder
@ -429,7 +429,7 @@ func (k Keeper) CloseAuction(ctx sdk.Context, auctionID uint64) sdk.Error {
return err return err
} }
default: default:
panic("unrecognized auction type") return types.ErrUnrecognizedAuctionType(k.codespace)
} }
k.DeleteAuction(ctx, auctionID) k.DeleteAuction(ctx, auctionID)

View File

@ -76,7 +76,7 @@ func TestAuctionBidding(t *testing.T) {
name string name string
auctionArgs auctionArgs auctionArgs auctionArgs
bidArgs bidArgs bidArgs bidArgs
expectedError string expectedError sdk.CodeType
expectedEndTime time.Time expectedEndTime time.Time
expectedBidder sdk.AccAddress expectedBidder sdk.AccAddress
expectedBid sdk.Coin expectedBid sdk.Coin
@ -86,7 +86,7 @@ func TestAuctionBidding(t *testing.T) {
"basic: auction doesn't exist", "basic: auction doesn't exist",
auctionArgs{Surplus, "", c("token1", 1), c("token2", 1), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}}, auctionArgs{Surplus, "", c("token1", 1), c("token2", 1), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}},
bidArgs{buyer, c("token2", 10), nil}, bidArgs{buyer, c("token2", 10), nil},
"auction doesn't exist", types.CodeAuctionNotFound,
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 10), c("token2", 10),
@ -96,7 +96,7 @@ func TestAuctionBidding(t *testing.T) {
"surplus: normal", "surplus: normal",
auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}}, auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}},
bidArgs{buyer, c("token2", 10), nil}, bidArgs{buyer, c("token2", 10), nil},
"", sdk.CodeType(0),
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 10), c("token2", 10),
@ -106,7 +106,7 @@ func TestAuctionBidding(t *testing.T) {
"surplus: second bidder", "surplus: second bidder",
auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}}, auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}},
bidArgs{buyer, c("token2", 10), secondBuyer}, bidArgs{buyer, c("token2", 10), secondBuyer},
"", sdk.CodeType(0),
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
secondBuyer, secondBuyer,
c("token2", 11), c("token2", 11),
@ -116,7 +116,7 @@ func TestAuctionBidding(t *testing.T) {
"surplus: invalid bid denom", "surplus: invalid bid denom",
auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}}, auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}},
bidArgs{buyer, c("badtoken", 10), nil}, bidArgs{buyer, c("badtoken", 10), nil},
"bid denom doesn't match auction", types.CodeInvalidBidDenom,
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 10), c("token2", 10),
@ -126,7 +126,7 @@ func TestAuctionBidding(t *testing.T) {
"surplus: invalid bid (equal)", "surplus: invalid bid (equal)",
auctionArgs{Surplus, modName, c("token1", 100), c("token2", 0), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}}, auctionArgs{Surplus, modName, c("token1", 100), c("token2", 0), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}},
bidArgs{buyer, c("token2", 0), nil}, bidArgs{buyer, c("token2", 0), nil},
"bid not greater than last bid", types.CodeBidTooSmall,
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 10), c("token2", 10),
@ -136,7 +136,7 @@ func TestAuctionBidding(t *testing.T) {
"debt: normal", "debt: normal",
auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 20), []sdk.AccAddress{}, []sdk.Int{}}, // initial bid, lot auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 20), []sdk.AccAddress{}, []sdk.Int{}}, // initial bid, lot
bidArgs{buyer, c("token1", 10), nil}, bidArgs{buyer, c("token1", 10), nil},
"", sdk.CodeType(0),
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 100), c("token2", 100),
@ -146,7 +146,7 @@ func TestAuctionBidding(t *testing.T) {
"debt: second bidder", "debt: second bidder",
auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 20), []sdk.AccAddress{}, []sdk.Int{}}, // initial bid, lot auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 20), []sdk.AccAddress{}, []sdk.Int{}}, // initial bid, lot
bidArgs{buyer, c("token1", 10), secondBuyer}, bidArgs{buyer, c("token1", 10), secondBuyer},
"", sdk.CodeType(0),
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
secondBuyer, secondBuyer,
c("token2", 100), c("token2", 100),
@ -156,7 +156,7 @@ func TestAuctionBidding(t *testing.T) {
"debt: invalid lot denom", "debt: invalid lot denom",
auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 20), []sdk.AccAddress{}, []sdk.Int{}}, // initial bid, lot auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 20), []sdk.AccAddress{}, []sdk.Int{}}, // initial bid, lot
bidArgs{buyer, c("badtoken", 10), nil}, bidArgs{buyer, c("badtoken", 10), nil},
"lot denom doesn't match auction", types.CodeInvalidLotDenom,
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token1", 20), c("token1", 20),
@ -166,7 +166,7 @@ func TestAuctionBidding(t *testing.T) {
"debt: invalid lot size (larger)", "debt: invalid lot size (larger)",
auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 20), []sdk.AccAddress{}, []sdk.Int{}}, auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 20), []sdk.AccAddress{}, []sdk.Int{}},
bidArgs{buyer, c("token1", 21), nil}, bidArgs{buyer, c("token1", 21), nil},
"lot not smaller than last lot", types.CodeLotTooLarge,
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token1", 20), c("token1", 20),
@ -176,7 +176,7 @@ func TestAuctionBidding(t *testing.T) {
"collateral [forward]: normal", "collateral [forward]: normal",
auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
bidArgs{buyer, c("token2", 10), nil}, bidArgs{buyer, c("token2", 10), nil},
"", sdk.CodeType(0),
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 10), c("token2", 10),
@ -186,7 +186,7 @@ func TestAuctionBidding(t *testing.T) {
"collateral [forward]: second bidder", "collateral [forward]: second bidder",
auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
bidArgs{buyer, c("token2", 10), secondBuyer}, bidArgs{buyer, c("token2", 10), secondBuyer},
"", sdk.CodeType(0),
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
secondBuyer, secondBuyer,
c("token2", 11), c("token2", 11),
@ -196,7 +196,7 @@ func TestAuctionBidding(t *testing.T) {
"collateral [forward]: invalid bid denom", "collateral [forward]: invalid bid denom",
auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
bidArgs{buyer, c("badtoken", 10), nil}, bidArgs{buyer, c("badtoken", 10), nil},
"bid denom doesn't match auction", types.CodeInvalidBidDenom,
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 10), c("token2", 10),
@ -206,7 +206,7 @@ func TestAuctionBidding(t *testing.T) {
"collateral [forward]: invalid bid size (smaller)", "collateral [forward]: invalid bid size (smaller)",
auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
bidArgs{buyer, c("token2", 0), nil}, // lot, bid bidArgs{buyer, c("token2", 0), nil}, // lot, bid
"auction in forward phase, new bid not higher than last bid", types.CodeBidTooSmall,
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 10), c("token2", 10),
@ -216,7 +216,7 @@ func TestAuctionBidding(t *testing.T) {
"collateral [forward]: invalid bid size (greater than max)", "collateral [forward]: invalid bid size (greater than max)",
auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
bidArgs{buyer, c("token2", 101), nil}, // lot, bid bidArgs{buyer, c("token2", 101), nil}, // lot, bid
"bid higher than max bid", types.CodeBidTooLarge,
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 10), c("token2", 10),
@ -226,7 +226,7 @@ func TestAuctionBidding(t *testing.T) {
"collateral [reverse]: normal", "collateral [reverse]: normal",
auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
bidArgs{buyer, c("token1", 15), nil}, bidArgs{buyer, c("token1", 15), nil},
"", sdk.CodeType(0),
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 50), c("token2", 50),
@ -236,7 +236,7 @@ func TestAuctionBidding(t *testing.T) {
"collateral [reverse]: second bidder", "collateral [reverse]: second bidder",
auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
bidArgs{buyer, c("token1", 15), secondBuyer}, bidArgs{buyer, c("token1", 15), secondBuyer},
"", sdk.CodeType(0),
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
secondBuyer, secondBuyer,
c("token2", 50), c("token2", 50),
@ -246,7 +246,7 @@ func TestAuctionBidding(t *testing.T) {
"collateral [reverse]: invalid lot denom", "collateral [reverse]: invalid lot denom",
auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
bidArgs{buyer, c("badtoken", 15), nil}, bidArgs{buyer, c("badtoken", 15), nil},
"lot denom doesn't match auction", types.CodeInvalidLotDenom,
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 50), c("token2", 50),
@ -256,7 +256,7 @@ func TestAuctionBidding(t *testing.T) {
"collateral [reverse]: invalid lot size (equal)", "collateral [reverse]: invalid lot size (equal)",
auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
bidArgs{buyer, c("token1", 20), nil}, bidArgs{buyer, c("token1", 20), nil},
"auction in reverse phase, new bid not less than previous amount", types.CodeLotTooLarge,
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 50), c("token2", 50),
@ -266,7 +266,7 @@ func TestAuctionBidding(t *testing.T) {
"collateral [reverse]: invalid lot size (greater)", "collateral [reverse]: invalid lot size (greater)",
auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
bidArgs{buyer, c("token1", 21), nil}, bidArgs{buyer, c("token1", 21), nil},
"auction in reverse phase, new bid not less than previous amount", types.CodeLotTooLarge,
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 50), c("token2", 50),
@ -276,7 +276,7 @@ func TestAuctionBidding(t *testing.T) {
"basic: closed auction", "basic: closed auction",
auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}}, auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}},
bidArgs{buyer, c("token2", 10), nil}, bidArgs{buyer, c("token2", 10), nil},
"auction has closed", types.CodeAuctionHasExpired,
someTime.Add(types.DefaultBidDuration), someTime.Add(types.DefaultBidDuration),
buyer, buyer,
c("token2", 10), c("token2", 10),
@ -287,7 +287,7 @@ func TestAuctionBidding(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
// Start Auction // Start Auction
var id uint64 var id uint64
var err error var err sdk.Error
switch tc.auctionArgs.auctionType { switch tc.auctionArgs.auctionType {
case Surplus: case Surplus:
id, _ = keeper.StartSurplusAuction(ctx, tc.auctionArgs.seller, tc.auctionArgs.lot, tc.auctionArgs.bid.Denom) id, _ = keeper.StartSurplusAuction(ctx, tc.auctionArgs.seller, tc.auctionArgs.lot, tc.auctionArgs.bid.Denom)
@ -341,8 +341,8 @@ func TestAuctionBidding(t *testing.T) {
require.Equal(t, tc.expectedBid, auction.GetBid()) require.Equal(t, tc.expectedBid, auction.GetBid())
require.Equal(t, tc.expectedEndTime, auction.GetEndTime()) require.Equal(t, tc.expectedEndTime, auction.GetEndTime())
} else { } else {
// Check expected error message // Check expected error code type
require.Contains(t, err.Error(), tc.expectedError) require.Equal(t, tc.expectedError, err.Result().Code)
} }
}) })
} }

View File

@ -18,6 +18,7 @@ type Keeper struct {
storeKey sdk.StoreKey storeKey sdk.StoreKey
cdc *codec.Codec cdc *codec.Codec
paramSubspace subspace.Subspace paramSubspace subspace.Subspace
codespace sdk.CodespaceType
} }
// NewKeeper returns a new auction keeper. // NewKeeper returns a new auction keeper.
@ -46,7 +47,7 @@ func (k Keeper) GetNextAuctionID(ctx sdk.Context) (uint64, sdk.Error) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
bz := store.Get(types.NextAuctionIDKey) bz := store.Get(types.NextAuctionIDKey)
if bz == nil { if bz == nil {
return 0, sdk.ErrInternal("initial auction ID hasn't been set") return 0, types.ErrInvalidInitialAuctionID(k.codespace)
} }
return types.Uint64FromBytes(bz), nil return types.Uint64FromBytes(bz), nil
} }

View File

@ -29,7 +29,7 @@ func queryAuctions(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) (res [
bz, err2 := codec.MarshalJSONIndent(keeper.cdc, auctionsList) bz, err2 := codec.MarshalJSONIndent(keeper.cdc, auctionsList)
if err2 != nil { if err2 != nil {
panic("could not marshal result to JSON") return nil, sdk.ErrInternal("could not marshal result to JSON")
} }
return bz, nil return bz, nil

92
x/auction/types/errors.go Normal file
View File

@ -0,0 +1,92 @@
// DONTCOVER
package types
import (
"fmt"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Error codes specific to auction module
const (
DefaultCodespace sdk.CodespaceType = ModuleName
CodeInvalidInitialAuctionID sdk.CodeType = 1
CodeInvalidModulePermissions sdk.CodeType = 2
CodeUnrecognizedAuctionType sdk.CodeType = 3
CodeAuctionNotFound sdk.CodeType = 4
CodeAuctionHasNotExpired sdk.CodeType = 5
CodeAuctionHasExpired sdk.CodeType = 6
CodeInvalidBidDenom sdk.CodeType = 7
CodeInvalidLotDenom sdk.CodeType = 8
CodeBidTooSmall sdk.CodeType = 9
CodeBidTooLarge sdk.CodeType = 10
CodeLotTooLarge sdk.CodeType = 11
CodeCollateralAuctionIsInReversePhase sdk.CodeType = 12
CodeCollateralAuctionIsInForwardPhase sdk.CodeType = 13
)
// ErrInvalidInitialAuctionID error for when the initial auction ID hasn't been set
func ErrInvalidInitialAuctionID(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidInitialAuctionID, fmt.Sprintf("initial auction ID hasn't been set"))
}
// ErrInvalidModulePermissions error for when module doesn't have valid permissions
func ErrInvalidModulePermissions(codespace sdk.CodespaceType, permission string) sdk.Error {
return sdk.NewError(codespace, CodeInvalidModulePermissions, fmt.Sprintf("module does not have required permission '%s'", permission))
}
// ErrUnrecognizedAuctionType error for unrecognized auction type
func ErrUnrecognizedAuctionType(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeUnrecognizedAuctionType, fmt.Sprintf("unrecognized auction type"))
}
// ErrAuctionNotFound error for when an auction is not found
func ErrAuctionNotFound(codespace sdk.CodespaceType, id uint64) sdk.Error {
return sdk.NewError(codespace, CodeAuctionNotFound, fmt.Sprintf("auction %d was not found", id))
}
// ErrAuctionHasNotExpired error for attempting to close an auction that has not passed its end time
func ErrAuctionHasNotExpired(codespace sdk.CodespaceType, blockTime time.Time, endTime time.Time) sdk.Error {
return sdk.NewError(codespace, CodeAuctionHasNotExpired, fmt.Sprintf("auction can't be closed as curent block time (%v) has not passed auction end time (%v)", blockTime, endTime))
}
// ErrAuctionHasExpired error for when an auction is closed and unavailable for bidding
func ErrAuctionHasExpired(codespace sdk.CodespaceType, id uint64) sdk.Error {
return sdk.NewError(codespace, CodeAuctionHasExpired, fmt.Sprintf("auction %d has closed", id))
}
// ErrInvalidBidDenom error for when bid denom doesn't match auction bid denom
func ErrInvalidBidDenom(codespace sdk.CodespaceType, bidDenom string, auctionBidDenom string) sdk.Error {
return sdk.NewError(codespace, CodeInvalidBidDenom, fmt.Sprintf("bid denom %s doesn't match auction bid denom %s", bidDenom, auctionBidDenom))
}
// ErrInvalidLotDenom error for when lot denom doesn't match auction lot denom
func ErrInvalidLotDenom(codespace sdk.CodespaceType, lotDenom string, auctionLotDenom string) sdk.Error {
return sdk.NewError(codespace, CodeInvalidLotDenom, fmt.Sprintf("lot denom %s doesn't match auction lot denom %s", lotDenom, auctionLotDenom))
}
// ErrBidTooSmall error for when bid is not greater than auction's last bid
func ErrBidTooSmall(codespace sdk.CodespaceType, bid sdk.Coin, lastBid sdk.Coin) sdk.Error {
return sdk.NewError(codespace, CodeBidTooSmall, fmt.Sprintf("bid %s is smaller than auction's last bid %s", bid.String(), lastBid.String()))
}
// ErrBidTooLarge error for when bid is larger than auction's maximum allowed bid
func ErrBidTooLarge(codespace sdk.CodespaceType, bid sdk.Coin, maxBid sdk.Coin) sdk.Error {
return sdk.NewError(codespace, CodeBidTooLarge, fmt.Sprintf("bid %s is greater than auction's max bid %s", bid.String(), maxBid.String()))
}
// ErrLotTooLarge error for when lot is not smaller than auction's last lot
func ErrLotTooLarge(codespace sdk.CodespaceType, lot sdk.Coin, lastLot sdk.Coin) sdk.Error {
return sdk.NewError(codespace, CodeLotTooLarge, fmt.Sprintf("lot %s is not less than auction's last lot %s", lot.String(), lastLot.String()))
}
// ErrCollateralAuctionIsInReversePhase error for when attempting to place a forward bid on a collateral auction in reverse phase
func ErrCollateralAuctionIsInReversePhase(codespace sdk.CodespaceType, id uint64) sdk.Error {
return sdk.NewError(codespace, CodeCollateralAuctionIsInReversePhase, fmt.Sprintf("invalid bid - auction %d is in reverse phase", id))
}
// ErrCollateralAuctionIsInForwardPhase error for when attempting to place a reverse bid on a collateral auction in forward phase
func ErrCollateralAuctionIsInForwardPhase(codespace sdk.CodespaceType, id uint64) sdk.Error {
return sdk.NewError(codespace, CodeCollateralAuctionIsInForwardPhase, fmt.Sprintf("invalid bid - auction %d is in forward phase", id))
}

View File

@ -33,7 +33,7 @@ func (msg MsgPlaceBid) ValidateBasic() sdk.Error {
return sdk.ErrInternal("invalid (empty) bidder address") return sdk.ErrInternal("invalid (empty) bidder address")
} }
if !msg.Amount.IsValid() { if !msg.Amount.IsValid() {
return sdk.ErrInternal("invalid bid amount") return sdk.ErrInvalidCoins(msg.Amount.String())
} }
return nil return nil
} }