mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-25 15:55:18 +00:00
update endblocker test
This commit is contained in:
parent
0d72f47bc2
commit
8a4109ff26
@ -4,40 +4,53 @@ import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/supply"
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/x/auction"
|
||||
"github.com/kava-labs/kava/x/liquidator"
|
||||
)
|
||||
|
||||
func TestKeeper_EndBlocker(t *testing.T) {
|
||||
// Setup
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(1)
|
||||
seller := addrs[0]
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(2)
|
||||
buyer := addrs[0]
|
||||
recipient := addrs[1]
|
||||
sellerModName := liquidator.ModuleName
|
||||
//sellerAddr := supply.NewModuleAddress(sellerModName)
|
||||
|
||||
tApp := app.NewTestApp()
|
||||
sellerAcc := supply.NewEmptyModuleAccount(sellerModName)
|
||||
require.NoError(t, sellerAcc.SetCoins(cs(c("token1", 100), c("token2", 100))))
|
||||
tApp.InitializeFromGenesisStates(
|
||||
app.NewAuthGenState(addrs, []sdk.Coins{cs(c("token1", 100), c("token2", 100))}),
|
||||
NewAuthGenStateFromAccs(authexported.GenesisAccounts{
|
||||
auth.NewBaseAccount(buyer, cs(c("token1", 100), c("token2", 100)), nil, 0, 0),
|
||||
sellerAcc,
|
||||
}),
|
||||
)
|
||||
|
||||
ctx := tApp.NewContext(true, abci.Header{})
|
||||
keeper := tApp.GetAuctionKeeper()
|
||||
|
||||
auctionID, err := keeper.StartForwardAuction(ctx, seller, c("token1", 20), c("token2", 0))
|
||||
auctionID, err := keeper.StartForwardReverseAuction(ctx, sellerModName, c("token1", 20), c("token2", 50), recipient)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, keeper.PlaceBid(ctx, auctionID, buyer, c("token2", 30), c("token1", 20)))
|
||||
|
||||
// Run the endblocker, simulating a block height just before auction expiry
|
||||
preExpiryHeight := ctx.BlockHeight() + int64(auction.DefaultMaxAuctionDuration) - 1
|
||||
auction.EndBlocker(ctx.WithBlockHeight(preExpiryHeight), keeper)
|
||||
// Run the endblocker, simulating a block time 1ns before auction expiry
|
||||
preExpiryTime := ctx.BlockTime().Add(auction.DefaultBidDuration - 1)
|
||||
auction.EndBlocker(ctx.WithBlockTime(preExpiryTime), keeper)
|
||||
|
||||
// Check auction has not been closed yet
|
||||
_, found := keeper.GetAuction(ctx, auctionID)
|
||||
require.True(t, found)
|
||||
|
||||
// Run the endblocker, simulating a block height just after auction expiry
|
||||
expiryHeight := preExpiryHeight + 1
|
||||
auction.EndBlocker(ctx.WithBlockHeight(expiryHeight), keeper)
|
||||
// Run the endblocker, simulating a block time equal to auction expiry
|
||||
expiryTime := ctx.BlockTime().Add(auction.DefaultBidDuration)
|
||||
auction.EndBlocker(ctx.WithBlockTime(expiryTime), keeper)
|
||||
|
||||
// Check auction has been closed
|
||||
_, found = keeper.GetAuction(ctx, auctionID)
|
||||
@ -46,3 +59,8 @@ func TestKeeper_EndBlocker(t *testing.T) {
|
||||
|
||||
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
|
||||
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
|
||||
|
||||
func NewAuthGenStateFromAccs(accounts authexported.GenesisAccounts) app.GenesisState {
|
||||
authGenesis := auth.NewGenesisState(auth.DefaultParams(), accounts)
|
||||
return app.GenesisState{auth.ModuleName: auth.ModuleCdc.MustMarshalJSON(authGenesis)}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ const (
|
||||
RouterKey = types.RouterKey
|
||||
DefaultParamspace = types.DefaultParamspace
|
||||
DefaultMaxAuctionDuration = types.DefaultMaxAuctionDuration
|
||||
DefaultMaxBidDuration = types.DefaultMaxBidDuration
|
||||
DefaultBidDuration = types.DefaultBidDuration
|
||||
QueryGetAuction = types.QueryGetAuction
|
||||
)
|
||||
|
||||
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
Package auction is a module for creating generic auctions and allowing users to place bids until a timeout is reached.
|
||||
|
||||
TODO
|
||||
- investigate when exactly auctions close and verify queue/endblocker logic is ok
|
||||
- add more test cases, add stronger validation to user inputs
|
||||
- add minimum bid increment
|
||||
- decided whether to put auction params like default timeouts into the auctions themselves
|
||||
- add docs
|
||||
- Add constants for the module and route names
|
||||
- user facing things like cli, rest, querier, tags
|
||||
- custom error types, codespace
|
||||
*/
|
||||
package auction
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/kava-labs/kava/x/auction/types"
|
||||
)
|
||||
|
||||
// StartForwardAuction starts a normal auction.
|
||||
// StartForwardAuction starts a normal auction that mints the sold coins.
|
||||
func (k Keeper) StartForwardAuction(ctx sdk.Context, seller string, lot sdk.Coin, bidDenom string) (types.ID, sdk.Error) {
|
||||
// create auction
|
||||
auction := types.NewForwardAuction(seller, lot, bidDenom, ctx.BlockTime().Add(types.DefaultMaxAuctionDuration))
|
||||
@ -108,7 +108,12 @@ func (k Keeper) PlaceBid(ctx sdk.Context, auctionID types.ID, bidder sdk.AccAddr
|
||||
}
|
||||
|
||||
// store updated auction
|
||||
k.SetAuction(ctx, a) // TODO maybe move into above funcs
|
||||
existing, found := k.GetAuction(ctx, a.GetID())
|
||||
if found {
|
||||
k.RemoveFromQueue(ctx, existing.GetEndTime(), existing.GetID())
|
||||
}
|
||||
k.SetAuction(ctx, a)
|
||||
k.InsertIntoQueue(ctx, a.GetEndTime(), a.GetID())
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -149,7 +154,7 @@ func (k Keeper) PlaceBidForward(ctx sdk.Context, a types.ForwardAuction, bidder
|
||||
a.Bidder = bidder
|
||||
a.Bid = bid
|
||||
// increment timeout
|
||||
a.EndTime = earliestTime(ctx.BlockTime().Add(types.DefaultMaxBidDuration), a.MaxEndTime) // TODO write a min func for time types
|
||||
a.EndTime = earliestTime(ctx.BlockTime().Add(types.DefaultBidDuration), a.MaxEndTime)
|
||||
|
||||
return a, nil
|
||||
}
|
||||
@ -211,7 +216,7 @@ func (k Keeper) PlaceBidForwardReverse(ctx sdk.Context, a types.ForwardReverseAu
|
||||
a.Lot = lot
|
||||
a.Bid = bid
|
||||
// increment timeout
|
||||
a.EndTime = earliestTime(ctx.BlockTime().Add(types.DefaultMaxBidDuration), a.MaxEndTime)
|
||||
a.EndTime = earliestTime(ctx.BlockTime().Add(types.DefaultBidDuration), a.MaxEndTime)
|
||||
|
||||
return a, nil
|
||||
}
|
||||
@ -245,7 +250,7 @@ func (k Keeper) PlaceBidReverse(ctx sdk.Context, a types.ReverseAuction, bidder
|
||||
a.Bidder = bidder
|
||||
a.Lot = lot
|
||||
// increment timeout
|
||||
a.EndTime = earliestTime(ctx.BlockTime().Add(types.DefaultMaxBidDuration), a.MaxEndTime)
|
||||
a.EndTime = earliestTime(ctx.BlockTime().Add(types.DefaultBidDuration), a.MaxEndTime)
|
||||
|
||||
return a, nil
|
||||
}
|
||||
@ -282,6 +287,7 @@ func (k Keeper) CloseAuction(ctx sdk.Context, auctionID types.ID) sdk.Error {
|
||||
|
||||
// Delete auction from store (and queue)
|
||||
k.DeleteAuction(ctx, auctionID)
|
||||
k.RemoveFromQueue(ctx, auction.GetEndTime(), auction.GetID())
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -297,7 +303,6 @@ func (k Keeper) MintAndPayoutAuctionLot(ctx sdk.Context, a types.ReverseAuction)
|
||||
return nil
|
||||
}
|
||||
func (k Keeper) PayoutAuctionLot(ctx sdk.Context, a types.Auction) sdk.Error {
|
||||
// TODO this function is responsible for the addition of GetBidder and GetLot to auction interface. Could be split in to two funcs that operate on concrete auction types
|
||||
err := k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, a.GetBidder(), sdk.NewCoins(a.GetLot()))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -48,7 +48,7 @@ func TestForwardAuctionBasic(t *testing.T) {
|
||||
tApp.CheckBalance(t, ctx, sellerAddr, cs(c("token1", 80), c("token2", 100)))
|
||||
|
||||
// Close auction at just at auction expiry time
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultMaxBidDuration))
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultBidDuration))
|
||||
require.NoError(t, keeper.CloseAuction(ctx, auctionID))
|
||||
// Check buyer's coins increased
|
||||
tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 120), c("token2", 90)))
|
||||
@ -86,7 +86,7 @@ func TestReverseAuctionBasic(t *testing.T) {
|
||||
tApp.CheckBalance(t, ctx, buyerAddr, cs(c("token1", 20)))
|
||||
|
||||
// Close auction at just after auction expiry
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultMaxBidDuration))
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultBidDuration))
|
||||
require.NoError(t, keeper.CloseAuction(ctx, auctionID))
|
||||
// Check seller's coins increased
|
||||
tApp.CheckBalance(t, ctx, seller, cs(c("token1", 80), c("token2", 110)))
|
||||
@ -138,7 +138,7 @@ func TestForwardReverseAuctionBasic(t *testing.T) {
|
||||
tApp.CheckBalance(t, ctx, recipient, cs(c("token1", 105), c("token2", 100)))
|
||||
|
||||
// Close auction at just after auction expiry
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultMaxBidDuration))
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultBidDuration))
|
||||
require.NoError(t, keeper.CloseAuction(ctx, auctionID))
|
||||
// Check buyer's coins increased
|
||||
tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 115), c("token2", 50)))
|
||||
|
@ -66,6 +66,7 @@ func (k Keeper) storeNewAuction(ctx sdk.Context, auction types.Auction) (types.I
|
||||
auction = auction.WithID(newAuctionID)
|
||||
|
||||
k.SetAuction(ctx, auction)
|
||||
k.InsertIntoQueue(ctx, auction.GetEndTime(), auction.GetID())
|
||||
|
||||
err = k.IncrementNextAuctionID(ctx)
|
||||
if err != nil {
|
||||
|
@ -94,40 +94,40 @@ func TestIterateAuctionsByTime(t *testing.T) {
|
||||
keeper := tApp.GetAuctionKeeper()
|
||||
ctx := tApp.NewContext(true, abci.Header{})
|
||||
|
||||
// create a list of times
|
||||
queue := []struct {
|
||||
// setup byTime index
|
||||
byTimeIndex := []struct {
|
||||
endTime time.Time
|
||||
auctionID types.ID
|
||||
}{
|
||||
{time.Date(84, time.January, 1, 0, 0, 0, 0, time.UTC), 34345345},
|
||||
{time.Date(98, time.January, 2, 0, 0, 0, 0, time.UTC), 5},
|
||||
{time.Date(98, time.January, 2, 13, 5, 0, 0, time.UTC), 6},
|
||||
{time.Date(98, time.January, 2, 16, 0, 0, 0, time.UTC), 1},
|
||||
{time.Date(98, time.January, 2, 16, 0, 0, 0, time.UTC), 3},
|
||||
{time.Date(98, time.January, 2, 16, 0, 0, 0, time.UTC), 4},
|
||||
{time.Date(98, time.January, 2, 16, 0, 0, 1, time.UTC), 0}, // TODO tidy up redundant entries
|
||||
{time.Date(0, time.January, 1, 0, 0, 0, 0, time.UTC), 9999}, // distant past
|
||||
{time.Date(1998, time.January, 1, 11, 59, 59, 999999999, time.UTC), 1}, // just before cutoff
|
||||
{time.Date(1998, time.January, 1, 11, 59, 59, 999999999, time.UTC), 2}, //
|
||||
{time.Date(1998, time.January, 1, 12, 0, 0, 0, time.UTC), 3}, // equal to cutoff
|
||||
{time.Date(1998, time.January, 1, 12, 0, 0, 0, time.UTC), 4}, //
|
||||
{time.Date(1998, time.January, 1, 12, 0, 0, 1, time.UTC), 5}, // just after cutoff
|
||||
{time.Date(1998, time.January, 1, 12, 0, 0, 1, time.UTC), 6}, //
|
||||
{time.Date(9999, time.January, 1, 0, 0, 0, 0, time.UTC), 0}, // distant future
|
||||
}
|
||||
cutoffTime := time.Date(98, time.January, 2, 16, 0, 0, 0, time.UTC)
|
||||
|
||||
var expectedQueue []types.ID
|
||||
for _, i := range queue {
|
||||
if i.endTime.After(cutoffTime) { // only append items where endTime ≤ cutoffTime
|
||||
break
|
||||
}
|
||||
expectedQueue = append(expectedQueue, i.auctionID)
|
||||
}
|
||||
|
||||
// write and read queue
|
||||
for _, v := range queue {
|
||||
for _, v := range byTimeIndex {
|
||||
keeper.InsertIntoQueue(ctx, v.endTime, v.auctionID)
|
||||
}
|
||||
var readQueue []types.ID
|
||||
|
||||
// read out values from index up to a cutoff time and check they are as expected
|
||||
cutoffTime := time.Date(1998, time.January, 1, 12, 0, 0, 0, time.UTC)
|
||||
var expectedIndex []types.ID
|
||||
for _, v := range byTimeIndex {
|
||||
if v.endTime.Before(cutoffTime) || v.endTime.Equal(cutoffTime) { // endTime ≤ cutoffTime
|
||||
expectedIndex = append(expectedIndex, v.auctionID)
|
||||
}
|
||||
|
||||
}
|
||||
var readIndex []types.ID
|
||||
keeper.IterateAuctionsByTime(ctx, cutoffTime, func(id types.ID) bool {
|
||||
readQueue = append(readQueue, id)
|
||||
readIndex = append(readIndex, id)
|
||||
return false
|
||||
})
|
||||
|
||||
require.Equal(t, expectedQueue, readQueue)
|
||||
require.Equal(t, expectedIndex, readIndex)
|
||||
}
|
||||
|
||||
func convertIteratorToSlice(keeper keeper.Keeper, iterator sdk.Iterator) []types.ID {
|
||||
|
@ -13,7 +13,7 @@ const (
|
||||
// DefaultMaxAuctionDuration max length of auction
|
||||
DefaultMaxAuctionDuration time.Duration = 2 * 24 * time.Hour
|
||||
// DefaultBidDuration how long an auction gets extended when someone bids, roughly 3 hours in blocks
|
||||
DefaultMaxBidDuration time.Duration = 3 * time.Hour
|
||||
DefaultBidDuration time.Duration = 3 * time.Hour
|
||||
)
|
||||
|
||||
// Parameter keys
|
||||
@ -43,7 +43,7 @@ func NewAuctionParams(maxAuctionDuration time.Duration, bidDuration time.Duratio
|
||||
func DefaultAuctionParams() AuctionParams {
|
||||
return NewAuctionParams(
|
||||
DefaultMaxAuctionDuration,
|
||||
DefaultMaxBidDuration,
|
||||
DefaultBidDuration,
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user