forked from cerc-io/laconicd
Additional auction module commands (#3)
Reviewed-on: deep-stack/laconic2d#3 Co-authored-by: Prathamesh Musale <prathamesh.musale0@gmail.com> Co-committed-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
wnsUtils "git.vdb.to/cerc-io/laconic2d/utils"
|
||||
auctiontypes "git.vdb.to/cerc-io/laconic2d/x/auction"
|
||||
)
|
||||
|
||||
// GetTxCmd returns transaction commands for this module.
|
||||
func GetTxCmd() *cobra.Command {
|
||||
auctionTxCmd := &cobra.Command{
|
||||
Use: auctiontypes.ModuleName,
|
||||
Short: "Auction transactions subcommands",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
auctionTxCmd.AddCommand(
|
||||
GetCmdCommitBid(),
|
||||
GetCmdRevealBid(),
|
||||
)
|
||||
|
||||
return auctionTxCmd
|
||||
}
|
||||
|
||||
// GetCmdCommitBid is the CLI command for committing a bid.
|
||||
func GetCmdCommitBid() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "commit-bid [auction-id] [bid-amount]",
|
||||
Short: "Commit sealed bid",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bidAmount, err := sdk.ParseCoinNormalized(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mnemonic, err := wnsUtils.GenerateMnemonic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
chainId := viper.GetString("chain-id")
|
||||
auctionId := args[0]
|
||||
|
||||
reveal := map[string]interface{}{
|
||||
"chainId": chainId,
|
||||
"auctionId": auctionId,
|
||||
"bidderAddress": clientCtx.GetFromAddress().String(),
|
||||
"bidAmount": bidAmount.String(),
|
||||
"noise": mnemonic,
|
||||
}
|
||||
|
||||
commitHash, content, err := wnsUtils.GenerateHash(reveal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Save reveal file.
|
||||
err = os.WriteFile(fmt.Sprintf("%s-%s.json", clientCtx.GetFromName(), commitHash), content, 0o600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := auctiontypes.NewMsgCommitBid(auctionId, commitHash, clientCtx.GetFromAddress())
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdRevealBid is the CLI command for revealing a bid.
|
||||
func GetCmdRevealBid() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "reveal-bid [auction-id] [reveal-file-path]",
|
||||
Short: "Reveal bid",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
auctionId := args[0]
|
||||
revealFilePath := args[1]
|
||||
|
||||
revealBytes, err := os.ReadFile(revealFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := auctiontypes.NewMsgRevealBid(auctionId, hex.EncodeToString(revealBytes), clientCtx.GetFromAddress())
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
+543
-13
@@ -1,7 +1,11 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/collections"
|
||||
"cosmossdk.io/collections/indexes"
|
||||
@@ -14,9 +18,13 @@ import (
|
||||
auth "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
|
||||
wnsUtils "git.vdb.to/cerc-io/laconic2d/utils"
|
||||
auctiontypes "git.vdb.to/cerc-io/laconic2d/x/auction"
|
||||
)
|
||||
|
||||
// CompletedAuctionDeleteTimeout => Completed auctions are deleted after this timeout (after reveals end time).
|
||||
const CompletedAuctionDeleteTimeout = time.Hour * 24
|
||||
|
||||
type AuctionsIndexes struct {
|
||||
Owner *indexes.Multi[string, string, auctiontypes.Auction]
|
||||
}
|
||||
@@ -37,6 +45,23 @@ func newAuctionIndexes(sb *collections.SchemaBuilder) AuctionsIndexes {
|
||||
}
|
||||
}
|
||||
|
||||
type BidsIndexes struct {
|
||||
Bidder *indexes.ReversePair[string, string, auctiontypes.Bid]
|
||||
}
|
||||
|
||||
func (b BidsIndexes) IndexesList() []collections.Index[collections.Pair[string, string], auctiontypes.Bid] {
|
||||
return []collections.Index[collections.Pair[string, string], auctiontypes.Bid]{b.Bidder}
|
||||
}
|
||||
|
||||
func newBidsIndexes(sb *collections.SchemaBuilder) BidsIndexes {
|
||||
return BidsIndexes{
|
||||
Bidder: indexes.NewReversePair[auctiontypes.Bid](
|
||||
sb, auctiontypes.BidderAuctionIdIndexPrefix, "auction_id_by_bidder",
|
||||
collections.PairKeyCodec(collections.StringKey, collections.StringKey),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add required methods
|
||||
|
||||
type Keeper struct {
|
||||
@@ -53,7 +78,8 @@ type Keeper struct {
|
||||
// state management
|
||||
Schema collections.Schema
|
||||
Params collections.Item[auctiontypes.Params]
|
||||
Auctions *collections.IndexedMap[string, auctiontypes.Auction, AuctionsIndexes]
|
||||
Auctions *collections.IndexedMap[string, auctiontypes.Auction, AuctionsIndexes] // map: auctionId -> Auction, index: owner -> Auctions
|
||||
Bids *collections.IndexedMap[collections.Pair[string, string], auctiontypes.Bid, BidsIndexes] // map: (auctionId, bidder) -> Bid, index: bidder -> auctionId
|
||||
}
|
||||
|
||||
// NewKeeper creates a new Keeper instance
|
||||
@@ -68,8 +94,9 @@ func NewKeeper(
|
||||
cdc: cdc,
|
||||
accountKeeper: accountKeeper,
|
||||
bankKeeper: bankKeeper,
|
||||
Params: collections.NewItem(sb, auctiontypes.ParamsKeyPrefix, "params", codec.CollValue[auctiontypes.Params](cdc)),
|
||||
Auctions: collections.NewIndexedMap(sb, auctiontypes.AuctionsKeyPrefix, "auctions", collections.StringKey, codec.CollValue[auctiontypes.Auction](cdc), newAuctionIndexes(sb)),
|
||||
Params: collections.NewItem(sb, auctiontypes.ParamsPrefix, "params", codec.CollValue[auctiontypes.Params](cdc)),
|
||||
Auctions: collections.NewIndexedMap(sb, auctiontypes.AuctionsPrefix, "auctions", collections.StringKey, codec.CollValue[auctiontypes.Auction](cdc), newAuctionIndexes(sb)),
|
||||
Bids: collections.NewIndexedMap(sb, auctiontypes.BidsPrefix, "bids", collections.PairKeyCodec(collections.StringKey, collections.StringKey), codec.CollValue[auctiontypes.Bid](cdc), newBidsIndexes(sb)),
|
||||
// usageKeepers: usageKeepers,
|
||||
}
|
||||
|
||||
@@ -98,22 +125,112 @@ func (k Keeper) SaveAuction(ctx sdk.Context, auction *auctiontypes.Auction) erro
|
||||
// return nil
|
||||
}
|
||||
|
||||
// DeleteAuction - deletes the auction.
|
||||
func (k Keeper) DeleteAuction(ctx sdk.Context, auction auctiontypes.Auction) error {
|
||||
// Delete all bids first.
|
||||
bids, err := k.GetBids(ctx, auction.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, bid := range bids {
|
||||
if err := k.DeleteBid(ctx, *bid); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return k.Auctions.Remove(ctx, auction.Id)
|
||||
}
|
||||
|
||||
func (k Keeper) HasAuction(ctx sdk.Context, id string) (bool, error) {
|
||||
has, err := k.Auctions.Has(ctx, id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return has, nil
|
||||
}
|
||||
|
||||
func (k Keeper) SaveBid(ctx sdk.Context, bid *auctiontypes.Bid) error {
|
||||
key := collections.Join(bid.AuctionId, bid.BidderAddress)
|
||||
return k.Bids.Set(ctx, key, *bid)
|
||||
|
||||
// // Notify interested parties.
|
||||
// for _, keeper := range k.usageKeepers {
|
||||
// keeper.OnAuctionBid(ctx, bid.AuctionId, bid.BidderAddress)
|
||||
// }
|
||||
// return nil
|
||||
}
|
||||
|
||||
func (k Keeper) DeleteBid(ctx sdk.Context, bid auctiontypes.Bid) error {
|
||||
key := collections.Join(bid.AuctionId, bid.BidderAddress)
|
||||
return k.Bids.Remove(ctx, key)
|
||||
}
|
||||
|
||||
func (k Keeper) HasBid(ctx sdk.Context, id string, bidder string) (bool, error) {
|
||||
key := collections.Join(id, bidder)
|
||||
has, err := k.Bids.Has(ctx, key)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return has, nil
|
||||
}
|
||||
|
||||
func (k Keeper) GetBid(ctx sdk.Context, id string, bidder string) (auctiontypes.Bid, error) {
|
||||
key := collections.Join(id, bidder)
|
||||
bid, err := k.Bids.Get(ctx, key)
|
||||
if err != nil {
|
||||
return auctiontypes.Bid{}, err
|
||||
}
|
||||
|
||||
return bid, nil
|
||||
}
|
||||
|
||||
// GetBids gets the auction bids.
|
||||
func (k Keeper) GetBids(ctx sdk.Context, id string) ([]*auctiontypes.Bid, error) {
|
||||
var bids []*auctiontypes.Bid
|
||||
|
||||
// TODO: Optimize using return by value?
|
||||
err := k.Bids.Walk(ctx, collections.NewPrefixedPairRange[string, string](id), func(key collections.Pair[string, string], value auctiontypes.Bid) (stop bool, err error) {
|
||||
bids = append(bids, &value)
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bids, nil
|
||||
}
|
||||
|
||||
// ListAuctions - get all auctions.
|
||||
func (k Keeper) ListAuctions(ctx sdk.Context) ([]auctiontypes.Auction, error) {
|
||||
var auctions []auctiontypes.Auction
|
||||
|
||||
iter, err := k.Auctions.Iterate(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
auction, err := iter.Value()
|
||||
return iter.Values()
|
||||
}
|
||||
|
||||
// MatchAuctions - get all matching auctions.
|
||||
func (k Keeper) MatchAuctions(ctx sdk.Context, matchFn func(*auctiontypes.Auction) (bool, error)) ([]*auctiontypes.Auction, error) {
|
||||
var auctions []*auctiontypes.Auction
|
||||
|
||||
err := k.Auctions.Walk(ctx, nil, func(key string, value auctiontypes.Auction) (stop bool, err error) {
|
||||
auctionMatched, err := matchFn(&value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return false, err
|
||||
}
|
||||
|
||||
auctions = append(auctions, auction)
|
||||
if auctionMatched {
|
||||
auctions = append(auctions, &value)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return auctions, nil
|
||||
@@ -135,12 +252,38 @@ func (k Keeper) GetAuctionById(ctx sdk.Context, id string) (auctiontypes.Auction
|
||||
func (k Keeper) GetAuctionsByOwner(ctx sdk.Context, owner string) ([]auctiontypes.Auction, error) {
|
||||
iter, err := k.Auctions.Indexes.Owner.MatchExact(ctx, owner)
|
||||
if err != nil {
|
||||
return []auctiontypes.Auction{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return indexes.CollectValues(ctx, k.Auctions, iter)
|
||||
}
|
||||
|
||||
// QueryAuctionsByBidder - query auctions by bidder
|
||||
func (k Keeper) QueryAuctionsByBidder(ctx sdk.Context, bidderAddress string) ([]auctiontypes.Auction, error) {
|
||||
auctions := []auctiontypes.Auction{}
|
||||
|
||||
iter, err := k.Bids.Indexes.Bidder.MatchExact(ctx, bidderAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
keyPair, err := iter.PrimaryKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
auction, err := k.GetAuctionById(ctx, keyPair.K1())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
auctions = append(auctions, auction)
|
||||
}
|
||||
|
||||
return auctions, nil
|
||||
}
|
||||
|
||||
// CreateAuction creates a new auction.
|
||||
func (k Keeper) CreateAuction(ctx sdk.Context, msg auctiontypes.MsgCreateAuction) (*auctiontypes.Auction, error) {
|
||||
// TODO: Setup checks
|
||||
@@ -185,17 +328,189 @@ func (k Keeper) CreateAuction(ctx sdk.Context, msg auctiontypes.MsgCreateAuction
|
||||
}
|
||||
|
||||
// Save auction in store.
|
||||
k.SaveAuction(ctx, &auction)
|
||||
if err = k.SaveAuction(ctx, &auction); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &auction, nil
|
||||
}
|
||||
|
||||
func (k Keeper) CommitBid(ctx sdk.Context, msg auctiontypes.MsgCommitBid) (*auctiontypes.Bid, error) {
|
||||
panic("unimplemented")
|
||||
if has, err := k.HasAuction(ctx, msg.AuctionId); !has {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Auction not found.")
|
||||
}
|
||||
|
||||
auction, err := k.GetAuctionById(ctx, msg.AuctionId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if auction.Status != auctiontypes.AuctionStatusCommitPhase {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Auction is not in commit phase.")
|
||||
}
|
||||
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Take auction fees from account.
|
||||
totalFee := auction.CommitFee.Add(auction.RevealFee)
|
||||
sdkErr := k.bankKeeper.SendCoinsFromAccountToModule(ctx, signerAddress, auctiontypes.ModuleName, sdk.NewCoins(totalFee))
|
||||
if sdkErr != nil {
|
||||
return nil, sdkErr
|
||||
}
|
||||
|
||||
// Check if an old bid already exists, if so, return old bids auction fee (update bid scenario).
|
||||
bidder := signerAddress.String()
|
||||
bidExists, err := k.HasBid(ctx, msg.AuctionId, bidder)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if bidExists {
|
||||
oldBid, err := k.GetBid(ctx, msg.AuctionId, bidder)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
oldTotalFee := oldBid.CommitFee.Add(oldBid.RevealFee)
|
||||
sdkErr := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, auctiontypes.ModuleName, signerAddress, sdk.NewCoins(oldTotalFee))
|
||||
if sdkErr != nil {
|
||||
return nil, sdkErr
|
||||
}
|
||||
}
|
||||
|
||||
// Save new bid.
|
||||
bid := auctiontypes.Bid{
|
||||
AuctionId: msg.AuctionId,
|
||||
BidderAddress: bidder,
|
||||
Status: auctiontypes.BidStatusCommitted,
|
||||
CommitHash: msg.CommitHash,
|
||||
CommitTime: ctx.BlockTime(),
|
||||
CommitFee: auction.CommitFee,
|
||||
RevealFee: auction.RevealFee,
|
||||
}
|
||||
|
||||
if err = k.SaveBid(ctx, &bid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &bid, nil
|
||||
}
|
||||
|
||||
func (k Keeper) RevealBid(ctx sdk.Context, msg auctiontypes.MsgRevealBid) (*auctiontypes.Auction, error) {
|
||||
panic("unimplemented")
|
||||
if has, err := k.HasAuction(ctx, msg.AuctionId); !has {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Auction not found.")
|
||||
}
|
||||
|
||||
auction, err := k.GetAuctionById(ctx, msg.AuctionId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if auction.Status != auctiontypes.AuctionStatusRevealPhase {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Auction is not in reveal phase.")
|
||||
}
|
||||
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bidder := signerAddress.String()
|
||||
bidExists, err := k.HasBid(ctx, msg.AuctionId, bidder)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !bidExists {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Bid not found.")
|
||||
}
|
||||
|
||||
bid, err := k.GetBid(ctx, msg.AuctionId, bidder)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if bid.Status != auctiontypes.BidStatusCommitted {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Bid not in committed state.")
|
||||
}
|
||||
|
||||
revealBytes, err := hex.DecodeString(msg.Reveal)
|
||||
if err != nil {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal string.")
|
||||
}
|
||||
|
||||
cid, err := wnsUtils.CIDFromJSONBytes(revealBytes)
|
||||
if err != nil {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal JSON.")
|
||||
}
|
||||
|
||||
if bid.CommitHash != cid {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Commit hash mismatch.")
|
||||
}
|
||||
|
||||
var reveal map[string]interface{}
|
||||
err = json.Unmarshal(revealBytes, &reveal)
|
||||
if err != nil {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Reveal JSON unmarshal error.")
|
||||
}
|
||||
|
||||
chainID, err := wnsUtils.GetAttributeAsString(reveal, "chainId")
|
||||
if err != nil || chainID != ctx.ChainID() {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal chainID.")
|
||||
}
|
||||
|
||||
auctionID, err := wnsUtils.GetAttributeAsString(reveal, "auctionId")
|
||||
if err != nil || auctionID != msg.AuctionId {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal auction Id.")
|
||||
}
|
||||
|
||||
bidderAddress, err := wnsUtils.GetAttributeAsString(reveal, "bidderAddress")
|
||||
if err != nil {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal bid address.")
|
||||
}
|
||||
|
||||
if bidderAddress != signerAddress.String() {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Reveal bid address mismatch.")
|
||||
}
|
||||
|
||||
bidAmountStr, err := wnsUtils.GetAttributeAsString(reveal, "bidAmount")
|
||||
if err != nil {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal bid amount.")
|
||||
}
|
||||
|
||||
bidAmount, err := sdk.ParseCoinNormalized(bidAmountStr)
|
||||
if err != nil {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal bid amount.")
|
||||
}
|
||||
|
||||
if bidAmount.IsLT(auction.MinimumBid) {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Bid is lower than minimum bid.")
|
||||
}
|
||||
|
||||
// Lock bid amount.
|
||||
sdkErr := k.bankKeeper.SendCoinsFromAccountToModule(ctx, signerAddress, auctiontypes.ModuleName, sdk.NewCoins(bidAmount))
|
||||
if sdkErr != nil {
|
||||
return nil, sdkErr
|
||||
}
|
||||
|
||||
// Update bid.
|
||||
bid.BidAmount = bidAmount
|
||||
bid.RevealTime = ctx.BlockTime()
|
||||
bid.Status = auctiontypes.BidStatusRevealed
|
||||
if err = k.SaveBid(ctx, &bid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &auction, nil
|
||||
}
|
||||
|
||||
// GetParams gets the auction module's parameters.
|
||||
@@ -207,3 +522,218 @@ func (k Keeper) GetParams(ctx sdk.Context) (*auctiontypes.Params, error) {
|
||||
|
||||
return ¶ms, nil
|
||||
}
|
||||
|
||||
// GetAuctionModuleBalances gets the auction module account(s) balances.
|
||||
func (k Keeper) GetAuctionModuleBalances(ctx sdk.Context) sdk.Coins {
|
||||
moduleAddress := k.accountKeeper.GetModuleAddress(auctiontypes.ModuleName)
|
||||
balances := k.bankKeeper.GetAllBalances(ctx, moduleAddress)
|
||||
|
||||
return balances
|
||||
}
|
||||
|
||||
func (k Keeper) EndBlockerProcessAuctions(ctx sdk.Context) error {
|
||||
var err error
|
||||
|
||||
// Transition auction state (commit, reveal, expired, completed).
|
||||
if err = k.processAuctionPhases(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete stale auctions.
|
||||
return k.deleteCompletedAuctions(ctx)
|
||||
}
|
||||
|
||||
func (k Keeper) processAuctionPhases(ctx sdk.Context) error {
|
||||
auctions, err := k.MatchAuctions(ctx, func(_ *auctiontypes.Auction) (bool, error) {
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, auction := range auctions {
|
||||
// Commit -> Reveal state.
|
||||
if auction.Status == auctiontypes.AuctionStatusCommitPhase && ctx.BlockTime().After(auction.CommitsEndTime) {
|
||||
auction.Status = auctiontypes.AuctionStatusRevealPhase
|
||||
if err = k.SaveAuction(ctx, auction); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Logger().Info(fmt.Sprintf("Moved auction %s to reveal phase.", auction.Id))
|
||||
}
|
||||
|
||||
// Reveal -> Expired state.
|
||||
if auction.Status == auctiontypes.AuctionStatusRevealPhase && ctx.BlockTime().After(auction.RevealsEndTime) {
|
||||
auction.Status = auctiontypes.AuctionStatusExpired
|
||||
if err = k.SaveAuction(ctx, auction); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Logger().Info(fmt.Sprintf("Moved auction %s to expired state.", auction.Id))
|
||||
}
|
||||
|
||||
// If auction has expired, pick a winner from revealed bids.
|
||||
if auction.Status == auctiontypes.AuctionStatusExpired {
|
||||
if err = k.pickAuctionWinner(ctx, auction); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete completed stale auctions.
|
||||
func (k Keeper) deleteCompletedAuctions(ctx sdk.Context) error {
|
||||
auctions, err := k.MatchAuctions(ctx, func(auction *auctiontypes.Auction) (bool, error) {
|
||||
deleteTime := auction.RevealsEndTime.Add(CompletedAuctionDeleteTimeout)
|
||||
return auction.Status == auctiontypes.AuctionStatusCompleted && ctx.BlockTime().After(deleteTime), nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, auction := range auctions {
|
||||
ctx.Logger().Info(fmt.Sprintf("Deleting completed auction %s after timeout.", auction.Id))
|
||||
if err := k.DeleteAuction(ctx, *auction); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k Keeper) pickAuctionWinner(ctx sdk.Context, auction *auctiontypes.Auction) error {
|
||||
ctx.Logger().Info(fmt.Sprintf("Picking auction %s winner.", auction.Id))
|
||||
|
||||
var highestBid *auctiontypes.Bid
|
||||
var secondHighestBid *auctiontypes.Bid
|
||||
|
||||
bids, err := k.GetBids(ctx, auction.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, bid := range bids {
|
||||
ctx.Logger().Info(fmt.Sprintf("Processing bid %s %s", bid.BidderAddress, bid.BidAmount.String()))
|
||||
|
||||
// Only consider revealed bids.
|
||||
if bid.Status != auctiontypes.BidStatusRevealed {
|
||||
ctx.Logger().Info(fmt.Sprintf("Ignoring unrevealed bid %s %s", bid.BidderAddress, bid.BidAmount.String()))
|
||||
continue
|
||||
}
|
||||
|
||||
// Init highest bid.
|
||||
if highestBid == nil {
|
||||
highestBid = bid
|
||||
ctx.Logger().Info(fmt.Sprintf("Initializing 1st bid %s %s", bid.BidderAddress, bid.BidAmount.String()))
|
||||
continue
|
||||
}
|
||||
|
||||
//nolint: all
|
||||
if highestBid.BidAmount.IsLT(bid.BidAmount) {
|
||||
ctx.Logger().Info(fmt.Sprintf("New highest bid %s %s", bid.BidderAddress, bid.BidAmount.String()))
|
||||
|
||||
secondHighestBid = highestBid
|
||||
highestBid = bid
|
||||
|
||||
ctx.Logger().Info(fmt.Sprintf("Updated 1st bid %s %s", highestBid.BidderAddress, highestBid.BidAmount.String()))
|
||||
ctx.Logger().Info(fmt.Sprintf("Updated 2nd bid %s %s", secondHighestBid.BidderAddress, secondHighestBid.BidAmount.String()))
|
||||
|
||||
} else if secondHighestBid == nil || secondHighestBid.BidAmount.IsLT(bid.BidAmount) {
|
||||
ctx.Logger().Info(fmt.Sprintf("New 2nd highest bid %s %s", bid.BidderAddress, bid.BidAmount.String()))
|
||||
|
||||
secondHighestBid = bid
|
||||
ctx.Logger().Info(fmt.Sprintf("Updated 2nd bid %s %s", secondHighestBid.BidderAddress, secondHighestBid.BidAmount.String()))
|
||||
} else {
|
||||
ctx.Logger().Info(fmt.Sprintf("Ignoring bid as it doesn't affect 1st/2nd price %s %s", bid.BidderAddress, bid.BidAmount.String()))
|
||||
}
|
||||
}
|
||||
|
||||
// Highest bid is the winner, but pays second highest bid price.
|
||||
auction.Status = auctiontypes.AuctionStatusCompleted
|
||||
|
||||
if highestBid != nil {
|
||||
auction.WinnerAddress = highestBid.BidderAddress
|
||||
auction.WinningBid = highestBid.BidAmount
|
||||
|
||||
// Winner pays 2nd price, if a 2nd price exists.
|
||||
auction.WinningPrice = highestBid.BidAmount
|
||||
if secondHighestBid != nil {
|
||||
auction.WinningPrice = secondHighestBid.BidAmount
|
||||
}
|
||||
ctx.Logger().Info(fmt.Sprintf("Auction %s winner %s.", auction.Id, auction.WinnerAddress))
|
||||
ctx.Logger().Info(fmt.Sprintf("Auction %s winner bid %s.", auction.Id, auction.WinningBid.String()))
|
||||
ctx.Logger().Info(fmt.Sprintf("Auction %s winner price %s.", auction.Id, auction.WinningPrice.String()))
|
||||
} else {
|
||||
ctx.Logger().Info(fmt.Sprintf("Auction %s has no valid revealed bids (no winner).", auction.Id))
|
||||
}
|
||||
|
||||
if err := k.SaveAuction(ctx, auction); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, bid := range bids {
|
||||
bidderAddress, err := sdk.AccAddressFromBech32(bid.BidderAddress)
|
||||
if err != nil {
|
||||
ctx.Logger().Error(fmt.Sprintf("Invalid bidderAddress address. %v", err))
|
||||
panic("Invalid bidder address.")
|
||||
}
|
||||
|
||||
if bid.Status == auctiontypes.BidStatusRevealed {
|
||||
// Send reveal fee back to bidders that've revealed the bid.
|
||||
sdkErr := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, auctiontypes.ModuleName, bidderAddress, sdk.NewCoins(bid.RevealFee))
|
||||
if sdkErr != nil {
|
||||
ctx.Logger().Error(fmt.Sprintf("Auction error returning reveal fee: %v", sdkErr))
|
||||
panic(sdkErr)
|
||||
}
|
||||
}
|
||||
|
||||
// Send back locked bid amount to all bidders.
|
||||
sdkErr := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, auctiontypes.ModuleName, bidderAddress, sdk.NewCoins(bid.BidAmount))
|
||||
if sdkErr != nil {
|
||||
ctx.Logger().Error(fmt.Sprintf("Auction error returning bid amount: %v", sdkErr))
|
||||
panic(sdkErr)
|
||||
}
|
||||
}
|
||||
|
||||
// Process winner account (if nobody bids, there won't be a winner).
|
||||
if auction.WinnerAddress != "" {
|
||||
winnerAddress, err := sdk.AccAddressFromBech32(auction.WinnerAddress)
|
||||
if err != nil {
|
||||
ctx.Logger().Error(fmt.Sprintf("Invalid winner address. %v", err))
|
||||
panic("Invalid winner address.")
|
||||
}
|
||||
|
||||
// Take 2nd price from winner.
|
||||
sdkErr := k.bankKeeper.SendCoinsFromAccountToModule(ctx, winnerAddress, auctiontypes.ModuleName, sdk.NewCoins(auction.WinningPrice))
|
||||
if sdkErr != nil {
|
||||
ctx.Logger().Error(fmt.Sprintf("Auction error taking funds from winner: %v", sdkErr))
|
||||
panic(sdkErr)
|
||||
}
|
||||
|
||||
// Burn anything over the min. bid amount.
|
||||
amountToBurn := auction.WinningPrice.Sub(auction.MinimumBid)
|
||||
if amountToBurn.IsNegative() {
|
||||
ctx.Logger().Error("Auction coins to burn cannot be negative.")
|
||||
panic("Auction coins to burn cannot be negative.")
|
||||
}
|
||||
|
||||
// Use auction burn module account instead of actually burning coins to better keep track of supply.
|
||||
sdkErr = k.bankKeeper.SendCoinsFromModuleToModule(ctx, auctiontypes.ModuleName, auctiontypes.AuctionBurnModuleAccountName, sdk.NewCoins(amountToBurn))
|
||||
if sdkErr != nil {
|
||||
ctx.Logger().Error(fmt.Sprintf("Auction error burning coins: %v", sdkErr))
|
||||
panic(sdkErr)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Notify other modules (hook).
|
||||
// ctx.Logger().Info(fmt.Sprintf("Auction %s notifying %d modules.", auction.Id, len(k.usageKeepers)))
|
||||
// for _, keeper := range k.usageKeepers {
|
||||
// ctx.Logger().Info(fmt.Sprintf("Auction %s notifying module %s.", auction.Id, keeper.ModuleName()))
|
||||
// keeper.OnAuctionWinnerSelected(ctx, auction.Id)
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ import (
|
||||
auctiontypes "git.vdb.to/cerc-io/laconic2d/x/auction"
|
||||
)
|
||||
|
||||
// TODO: Add required read methods
|
||||
|
||||
var _ auctiontypes.QueryServer = queryServer{}
|
||||
|
||||
type queryServer struct {
|
||||
@@ -39,12 +37,12 @@ func (qs queryServer) Params(c context.Context, req *auctiontypes.QueryParamsReq
|
||||
func (qs queryServer) Auctions(c context.Context, req *auctiontypes.QueryAuctionsRequest) (*auctiontypes.QueryAuctionsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
resp, err := qs.k.ListAuctions(ctx)
|
||||
auctions, err := qs.k.ListAuctions(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &auctiontypes.QueryAuctionsResponse{Auctions: &auctiontypes.Auctions{Auctions: resp}}, nil
|
||||
return &auctiontypes.QueryAuctionsResponse{Auctions: &auctiontypes.Auctions{Auctions: auctions}}, nil
|
||||
}
|
||||
|
||||
// GetAuction queries an auction by id
|
||||
@@ -63,19 +61,56 @@ func (qs queryServer) GetAuction(c context.Context, req *auctiontypes.QueryAucti
|
||||
return &auctiontypes.QueryAuctionResponse{Auction: &auction}, nil
|
||||
}
|
||||
|
||||
// GetBid queries and auction bid
|
||||
// GetBid queries an auction bid by auction-id and bidder
|
||||
func (qs queryServer) GetBid(c context.Context, req *auctiontypes.QueryBidRequest) (*auctiontypes.QueryBidResponse, error) {
|
||||
panic("unimplemented")
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
if req.AuctionId == "" {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "auction id is required")
|
||||
}
|
||||
|
||||
if req.Bidder == "" {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "bidder address is required")
|
||||
}
|
||||
|
||||
bid, err := qs.k.GetBid(ctx, req.AuctionId, req.Bidder)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &auctiontypes.QueryBidResponse{Bid: &bid}, nil
|
||||
}
|
||||
|
||||
// GetBids queries all auction bids
|
||||
func (qs queryServer) GetBids(c context.Context, req *auctiontypes.QueryBidsRequest) (*auctiontypes.QueryBidsResponse, error) {
|
||||
panic("unimplemented")
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
if req.AuctionId == "" {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "auction id is required")
|
||||
}
|
||||
|
||||
bids, err := qs.k.GetBids(ctx, req.AuctionId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &auctiontypes.QueryBidsResponse{Bids: bids}, nil
|
||||
}
|
||||
|
||||
// AuctionsByBidder queries auctions by bidder
|
||||
func (qs queryServer) AuctionsByBidder(c context.Context, req *auctiontypes.QueryAuctionsByBidderRequest) (*auctiontypes.QueryAuctionsByBidderResponse, error) {
|
||||
panic("unimplemented")
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
if req.BidderAddress == "" {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "bidder address is required")
|
||||
}
|
||||
|
||||
auctions, err := qs.k.QueryAuctionsByBidder(ctx, req.BidderAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &auctiontypes.QueryAuctionsByBidderResponse{Auctions: &auctiontypes.Auctions{Auctions: auctions}}, nil
|
||||
}
|
||||
|
||||
// AuctionsByOwner queries auctions by owner
|
||||
@@ -96,5 +131,8 @@ func (qs queryServer) AuctionsByOwner(c context.Context, req *auctiontypes.Query
|
||||
|
||||
// GetAuctionModuleBalance queries the auction module account balance
|
||||
func (qs queryServer) GetAuctionModuleBalance(c context.Context, req *auctiontypes.QueryGetAuctionModuleBalanceRequest) (*auctiontypes.QueryGetAuctionModuleBalanceResponse, error) {
|
||||
panic("unimplemented")
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
balances := qs.k.GetAuctionModuleBalances(ctx)
|
||||
|
||||
return &auctiontypes.QueryGetAuctionModuleBalanceResponse{Balance: balances}, nil
|
||||
}
|
||||
|
||||
+5
-2
@@ -12,8 +12,11 @@ const (
|
||||
// Store prefixes
|
||||
var (
|
||||
// ParamsKey is the prefix for params key
|
||||
ParamsKeyPrefix = collections.NewPrefix(0)
|
||||
ParamsPrefix = collections.NewPrefix(0)
|
||||
|
||||
AuctionsKeyPrefix = collections.NewPrefix(1)
|
||||
AuctionsPrefix = collections.NewPrefix(1)
|
||||
AuctionOwnerIndexPrefix = collections.NewPrefix(2)
|
||||
|
||||
BidsPrefix = collections.NewPrefix(3)
|
||||
BidderAuctionIdIndexPrefix = collections.NewPrefix(4)
|
||||
)
|
||||
|
||||
@@ -3,13 +3,14 @@ package module
|
||||
import (
|
||||
"context"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"git.vdb.to/cerc-io/laconic2d/x/auction/keeper"
|
||||
)
|
||||
|
||||
// EndBlocker is called every block
|
||||
func EndBlocker(ctx context.Context, k keeper.Keeper) error {
|
||||
// TODO: Implement
|
||||
// k.EndBlockerProcessAuctions(ctx)
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
|
||||
return nil
|
||||
return k.EndBlockerProcessAuctions(sdkCtx)
|
||||
}
|
||||
|
||||
@@ -43,6 +43,37 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
|
||||
{ProtoField: "owner_address"},
|
||||
},
|
||||
},
|
||||
{
|
||||
RpcMethod: "GetBid",
|
||||
Use: "get-bid [auction-id] [bidder]",
|
||||
Short: "Get auction bid by auction id and bidder",
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
|
||||
{ProtoField: "auction_id"},
|
||||
{ProtoField: "bidder"},
|
||||
},
|
||||
},
|
||||
{
|
||||
RpcMethod: "GetBids",
|
||||
Use: "get-bids [auction-id]",
|
||||
Short: "Get all auction bids",
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
|
||||
{ProtoField: "auction_id"},
|
||||
},
|
||||
},
|
||||
{
|
||||
RpcMethod: "AuctionsByBidder",
|
||||
Use: "by-bidder [bidder]",
|
||||
Short: "Get auctions list by bidder",
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{
|
||||
{ProtoField: "bidder_address"},
|
||||
},
|
||||
},
|
||||
{
|
||||
RpcMethod: "GetAuctionModuleBalance",
|
||||
Use: "balance",
|
||||
Short: "Get auction module account balances",
|
||||
PositionalArgs: []*autocliv1.PositionalArgDescriptor{},
|
||||
},
|
||||
},
|
||||
},
|
||||
Tx: &autocliv1.ServiceCommandDescriptor{
|
||||
@@ -61,6 +92,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
|
||||
},
|
||||
},
|
||||
},
|
||||
EnhanceCustomCommand: true, // Allow additional manual commands
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"cosmossdk.io/core/appmodule"
|
||||
gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
|
||||
"git.vdb.to/cerc-io/laconic2d/x/auction"
|
||||
"git.vdb.to/cerc-io/laconic2d/x/auction/client/cli"
|
||||
"git.vdb.to/cerc-io/laconic2d/x/auction/keeper"
|
||||
)
|
||||
|
||||
@@ -125,3 +127,8 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
|
||||
func (am AppModule) EndBlock(ctx context.Context) error {
|
||||
return EndBlocker(ctx, am.keeper)
|
||||
}
|
||||
|
||||
// Get the root tx command of this module
|
||||
func (AppModule) GetTxCmd() *cobra.Command {
|
||||
return cli.GetTxCmd()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package auction
|
||||
|
||||
import (
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
var _ sdk.Msg = &MsgCommitBid{}
|
||||
|
||||
// NewMsgCommitBid is the constructor function for MsgCommitBid.
|
||||
func NewMsgCommitBid(auctionID string, commitHash string, signer sdk.AccAddress) MsgCommitBid {
|
||||
return MsgCommitBid{
|
||||
AuctionId: auctionID,
|
||||
CommitHash: commitHash,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgCommitBid) ValidateBasic() error {
|
||||
if msg.Signer == "" {
|
||||
return errorsmod.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer address")
|
||||
}
|
||||
|
||||
if msg.AuctionId == "" {
|
||||
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "invalid auction id")
|
||||
}
|
||||
|
||||
if msg.CommitHash == "" {
|
||||
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "invalid commit hash")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewMsgRevealBid is the constructor function for MsgRevealBid.
|
||||
func NewMsgRevealBid(auctionId string, reveal string, signer sdk.AccAddress) MsgRevealBid {
|
||||
return MsgRevealBid{
|
||||
AuctionId: auctionId,
|
||||
Reveal: reveal,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgRevealBid) ValidateBasic() error {
|
||||
if msg.Signer == "" {
|
||||
return errorsmod.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer address")
|
||||
}
|
||||
|
||||
if msg.AuctionId == "" {
|
||||
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "invalid auction id")
|
||||
}
|
||||
|
||||
if msg.Reveal == "" {
|
||||
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "invalid reveal data")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -70,8 +70,8 @@ func NewKeeper(
|
||||
cdc: cdc,
|
||||
accountKeeper: accountKeeper,
|
||||
bankKeeper: bankKeeper,
|
||||
Params: collections.NewItem(sb, bondtypes.ParamsKeyPrefix, "params", codec.CollValue[bondtypes.Params](cdc)),
|
||||
Bonds: collections.NewIndexedMap(sb, bondtypes.BondsKeyPrefix, "bonds", collections.StringKey, codec.CollValue[bondtypes.Bond](cdc), newBondIndexes(sb)),
|
||||
Params: collections.NewItem(sb, bondtypes.ParamsPrefix, "params", codec.CollValue[bondtypes.Params](cdc)),
|
||||
Bonds: collections.NewIndexedMap(sb, bondtypes.BondsPrefix, "bonds", collections.StringKey, codec.CollValue[bondtypes.Bond](cdc), newBondIndexes(sb)),
|
||||
// usageKeepers: usageKeepers,
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -8,9 +8,8 @@ const (
|
||||
|
||||
// Store prefixes
|
||||
var (
|
||||
// ParamsKey is the prefix for params key
|
||||
ParamsKeyPrefix = collections.NewPrefix(0)
|
||||
ParamsPrefix = collections.NewPrefix(0)
|
||||
|
||||
BondsKeyPrefix = collections.NewPrefix(1)
|
||||
BondsPrefix = collections.NewPrefix(1)
|
||||
BondOwnerIndexPrefix = collections.NewPrefix(2)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user